Gitweb links:
...log
http://git.netsurf-browser.org/toolchains.git/shortlog/f114daf8f1208d8fc5...
...commit
http://git.netsurf-browser.org/toolchains.git/commit/f114daf8f1208d8fc501...
...tree
http://git.netsurf-browser.org/toolchains.git/tree/f114daf8f1208d8fc50169...
The branch, chris/gcc6-os3 has been updated
via f114daf8f1208d8fc501696f3de5a7d7e6e039ac (commit)
via e594f765231a6a1531e06d966ae23b3c2bae769d (commit)
from 4f49273829fe3275c937a836af5aa9f679823b08 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/toolchains.git/commit/?id=f114daf8f1208d8f...
commit f114daf8f1208d8fc501696f3de5a7d7e6e039ac
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
More tweaks
We now have a largely functional GCC6.4. Hooray!
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 3174e9a..31df799 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -3,7 +3,7 @@
# sources
-UPSTREAM_GCC_VERSION := 6.4.1b-20120122
+UPSTREAM_GCC_VERSION := 6.4.1b-20180122
UPSTREAM_GCC_TARBALL := v$(UPSTREAM_GCC_VERSION).tar.gz
UPSTREAM_GCC_URI :=
https://github.com/chris-y/gcc/archive/$(UPSTREAM_GCC_TARBALL)
@@ -156,9 +156,6 @@ $(BUILDSTEPS)/bootstrap-compiler.d: $(BUILDSTEPS)/bison.d
$(BUILDSTEPS)/srcdir-s
###
$(BUILDSTEPS)/srcdir-step3.d: $(BUILDSTEPS)/srcdir-step2.d
- for p in `ls $(RECIPES)/patches/gcc/*.p` ; do patch -d $(GCC_SRCDIR) -p0 <$$p ; done
- for dir in `find $(RECIPES)/files/gcc/ -type d | grep -v '\.svn' | sed
's#$(RECIPES)/files/gcc##'` ; do mkdir -p $(GCC_SRCDIR)$$dir ; done
- for file in `find $(RECIPES)/files/gcc/ -type f | grep -v '\.svn' | sed
's#$(RECIPES)/files/gcc##'` ; do cp -p $(RECIPES)/files/gcc$$file
$(GCC_SRCDIR)$$file ; done
touch $(GCC_SRCDIR)/lto-plugin/aclocal.m4 $(GCC_SRCDIR)/lto-plugin/Makefile.in
touch $(GCC_SRCDIR)/zlib/aclocal.m4 $(GCC_SRCDIR)/zlib/Makefile.in
touch $(GCC_SRCDIR)/libbacktrace/aclocal.m4 $(GCC_SRCDIR)/libbacktrace/Makefile.in
commitdiff
http://git.netsurf-browser.org/toolchains.git/commit/?id=e594f765231a6a15...
commit e594f765231a6a1531e06d966ae23b3c2bae769d
Author: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
Commit: Chris Young <chris(a)unsatisfactorysoftware.co.uk>
New approach
Fork bebbo's version of gcc, add our changes and create a tarball from that.
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 8a54b86..3174e9a 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -3,9 +3,9 @@
# sources
-UPSTREAM_GCC_VERSION := 6.4.0
-UPSTREAM_GCC_TARBALL := gcc-$(UPSTREAM_GCC_VERSION).tar.xz
-UPSTREAM_GCC_URI :=
http://ftp.gnu.org/gnu/gcc/gcc-$(UPSTREAM_GCC_VERSION)/$(UPSTREAM_GCC_TAR...
+UPSTREAM_GCC_VERSION := 6.4.1b-20120122
+UPSTREAM_GCC_TARBALL := v$(UPSTREAM_GCC_VERSION).tar.gz
+UPSTREAM_GCC_URI :=
https://github.com/chris-y/gcc/archive/$(UPSTREAM_GCC_TARBALL)
UPSTREAM_BINUTILS_VERSION := 2.14
# Not a tarball; so sue me
@@ -177,7 +177,7 @@ $(BUILDSTEPS)/srcdir-step2.d: $(BUILDSTEPS)/srcdir-step1.d
$(SOURCESDIR)/$(UPSTR
touch $@
$(BUILDSTEPS)/srcdir-step1.d: $(BUILDSTEPS)/$(UPSTREAM_GCC_TARBALL).d
- tar xJf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
+ tar xzf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
mv gcc-$(UPSTREAM_GCC_VERSION) $(GCC_SRCDIR)
touch $@
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
b/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
deleted file mode 100644
index 25088ee..0000000
--- a/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
+++ /dev/null
@@ -1,11008 +0,0 @@
-diff --git a/.cproject b/.cproject
-new file mode 100755
-index 000000000000..6db4cbe2447e
---- /dev/null
-+++ .cproject
-@@ -0,0 +1,188 @@
-+<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
-+<?fileVersion 4.0.0?><cproject
storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-+ <storageModule moduleId="org.eclipse.cdt.core.settings">
-+ <cconfiguration
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522">
-+ <storageModule
buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider"
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
moduleId="org.eclipse.cdt.core.settings" name="Debug">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.Cygwin_PE"
point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}"
buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe"
buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug"
cleanCommand="rm -rf" description=""
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
-+ <folderInfo
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522." name="/"
resourcePath="">
-+ <toolChain id="cdt.managedbuild.toolchain.gnu.cygwin.base.2053847551"
name="Cygwin GCC"
superClass="cdt.managedbuild.toolchain.gnu.cygwin.base">
-+ <targetPlatform archList="all"
binaryParser="org.eclipse.cdt.core.Cygwin_PE"
id="cdt.managedbuild.target.gnu.platform.cygwin.base.2091243283"
name="Debug Platform" osList="win32"
superClass="cdt.managedbuild.target.gnu.platform.cygwin.base"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Debug"
id="cdt.managedbuild.target.gnu.builder.cygwin.base.1660320342"
keepEnvironmentInBuildfile="false" managedBuildOn="false"
name="Gnu Make Builder"
superClass="cdt.managedbuild.target.gnu.builder.cygwin.base">
-+ <outputEntries>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED"
kind="outputPath" name=""/>
-+ </outputEntries>
-+ </builder>
-+ <tool id="cdt.managedbuild.tool.gnu.assembler.cygwin.base.607722454"
name="GCC Assembler"
superClass="cdt.managedbuild.tool.gnu.assembler.cygwin.base">
-+ <option id="gnu.both.asm.option.include.paths.2094451885"
name="Include paths (-I)"
superClass="gnu.both.asm.option.include.paths"
valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/amigaos-cross-toolchain/.build-m68k/build/gcc-6/gcc}""/>
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.assembler.input.1425989952"
superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.archiver.cygwin.base.2119049474"
name="GCC Archiver"
superClass="cdt.managedbuild.tool.gnu.archiver.cygwin.base"/>
-+ <tool
id="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968"
name="Cygwin C++ Compiler"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base">
-+ <option id="gnu.cpp.compiler.option.include.paths.466783605"
name="Include paths (-I)"
superClass="gnu.cpp.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/gcc-6/libcpp/include}""/>
-+ <listOptionValue builtIn="false"
value=""D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc""/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.optimization.level.193715843"
name="Optimization Level"
superClass="gnu.cpp.compiler.option.optimization.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.optimization.level.none"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.2136883244"
name="Debug Level"
superClass="gnu.cpp.compiler.option.debugging.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.debugging.level.max"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.807277038"
name="Defined symbols (-D)"
superClass="gnu.cpp.compiler.option.preprocessor.def"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
-+ </tool>
-+ <tool
id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604"
name="Cygwin C Compiler"
superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base">
-+ <option id="gnu.c.compiler.option.include.paths.692774379"
name="Include paths (-I)"
superClass="gnu.c.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/gcc-6/libcpp/include}""/>
-+ <listOptionValue builtIn="false"
value=""D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc""/>
-+ </option>
-+ <option defaultValue="gnu.c.optimization.level.none"
id="gnu.c.compiler.option.optimization.level.227992926" name="Optimization
Level" superClass="gnu.c.compiler.option.optimization.level"
useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.748883400"
name="Debug Level" superClass="gnu.c.compiler.option.debugging.level"
useByScannerDiscovery="false" value="gnu.c.debugging.level.max"
valueType="enumerated"/>
-+ <option
id="gnu.c.compiler.option.preprocessor.def.symbols.1982594045"
name="Defined symbols (-D)"
superClass="gnu.c.compiler.option.preprocessor.def.symbols"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313"
superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.c.linker.cygwin.base.344641511"
name="Cygwin C Linker"
superClass="cdt.managedbuild.tool.gnu.c.linker.cygwin.base"/>
-+ <tool
id="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base.968200320"
name="Cygwin C++ Linker"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base">
-+ <option id="gnu.cpp.link.option.libs.260033787"
name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.linker.input.1537937183"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency"
paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput"
paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry
excluding="ada/|doc/|fortran/|ginclude/|go/|java/|jit/|lto/|objc/|objcp/|po/|testsuite/|config/aarch64/|config/alpha/|config/arc/|config/arm/|config/avr/|config/bfin/|config/c6x/|config/cr16/|config/cris/|config/epiphany/|config/fr30/|config/frv/|config/ft32/|config/h8300/|config/i386/|config/ia64/|config/iq2000/|config/lm32/|config/m32c/|config/m32r/|config/mcore/|config/mep/|config/microblaze/|config/mips/|config/mmix/|config/mn10300/|config/moxie/|config/msp430/|config/nds32/|config/nios2/|config/nvptx/|config/pa/|config/pdp11/|config/rl78/|config/rs6000/|config/rx/|config/s390/|config/sh/|config/sparc/|config/spu/|config/stormy16/|config/tilegx/|config/tilepro/|config/v850/|config/vax/|config/visium/|config/vms/|config/xtensa/"
flags="VALUE_WORKSPACE_PATH" kind="sourcePath"
name="gcc"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ <cconfiguration
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954">
-+ <storageModule
buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider"
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
moduleId="org.eclipse.cdt.core.settings" name="Release">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.ELF"
point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}"
buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe"
buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release"
cleanCommand="rm -rf" description=""
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
name="Release"
parent="cdt.managedbuild.config.gnu.cross.exe.release">
-+ <folderInfo
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954." name="/"
resourcePath="">
-+ <toolChain
id="cdt.managedbuild.toolchain.gnu.cross.exe.release.101222491" name="Cross
GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
-+ <targetPlatform archList="all"
binaryParser="org.eclipse.cdt.core.ELF"
id="cdt.managedbuild.targetPlatform.gnu.cross.1798723854"
isAbstract="false" osList="all"
superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Release"
id="cdt.managedbuild.builder.gnu.cross.507087034"
keepEnvironmentInBuildfile="false" managedBuildOn="true"
name="Gnu Make Builder"
superClass="cdt.managedbuild.builder.gnu.cross"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466"
name="Cross GCC Compiler"
superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
-+ <option defaultValue="gnu.c.optimization.level.most"
id="gnu.c.compiler.option.optimization.level.1686563067" name="Optimization
Level" superClass="gnu.c.compiler.option.optimization.level"
useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.60172226"
name="Debug Level" superClass="gnu.c.compiler.option.debugging.level"
useByScannerDiscovery="false" value="gnu.c.debugging.level.none"
valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.include.paths.696908692"
name="Include paths (-I)"
superClass="gnu.c.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <option
id="gnu.c.compiler.option.preprocessor.def.symbols.652362073" name="Defined
symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656"
superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749"
name="Cross G++ Compiler"
superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
-+ <option id="gnu.cpp.compiler.option.optimization.level.2088586809"
name="Optimization Level"
superClass="gnu.cpp.compiler.option.optimization.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.optimization.level.most"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.1993778911"
name="Debug Level"
superClass="gnu.cpp.compiler.option.debugging.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.debugging.level.none"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.include.paths.1936413739"
name="Include paths (-I)"
superClass="gnu.cpp.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.625117841"
name="Defined symbols (-D)"
superClass="gnu.cpp.compiler.option.preprocessor.def"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.946489608"
name="Cross GCC Linker"
superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.738916918"
name="Cross G++ Linker"
superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.linker.input.1880308865"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency"
paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput"
paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1813524686"
name="Cross GCC Archiver"
superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1395544547"
name="Cross GCC Assembler"
superClass="cdt.managedbuild.tool.gnu.cross.assembler">
-+ <option id="gnu.both.asm.option.include.paths.1443815690"
name="Include paths (-I)"
superClass="gnu.both.asm.option.include.paths"
valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.assembler.input.1421786104"
superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry excluding="src"
flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath"
name=""/>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED"
kind="sourcePath" name="src"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <project id="debugwin.cdt.managedbuild.target.gnu.cross.exe.1884740625"
name="Executable"
projectType="cdt.managedbuild.target.gnu.cross.exe"/>
-+ </storageModule>
-+ <storageModule
moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-+ <storageModule moduleId="refreshScope" versionNumber="2">
-+ <configuration configurationName="Debug">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ <configuration configurationName="Release">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-+ <storageModule moduleId="scannerConfiguration">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466;cdt.managedbuild.tool.gnu.c.compiler.input.1150724656">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.c.compiler.502147450;cdt.managedbuild.tool.gnu.c.compiler.input.1173428818">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968;cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.216739552;cdt.managedbuild.tool.gnu.cpp.compiler.input.1269341019">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749;cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ </storageModule>
-+</cproject>
-diff --git a/.project b/.project
-new file mode 100644
-index 000000000000..500c9ee08dca
---- /dev/null
-+++ .project
-@@ -0,0 +1,34 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<projectDescription>
-+ <name>gcc-6</name>
-+ <comment></comment>
-+ <projects>
-+ </projects>
-+ <buildSpec>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-+ <triggers>clean,full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-+ <triggers>full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
-+ </buildSpec>
-+ <natures>
-+ <nature>org.eclipse.cdt.core.cnature</nature>
-+ <nature>org.eclipse.cdt.core.ccnature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-+ </natures>
-+ <linkedResources>
-+ <link>
-+ <name>build-gcc</name>
-+ <type>2</type>
-+ <location>D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6</location>
-+ </link>
-+ </linkedResources>
-+</projectDescription>
-diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
-new file mode 100755
-index 000000000000..caef162d88d1
---- /dev/null
-+++ .settings/language.settings.xml
-@@ -0,0 +1,25 @@
-+<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
-+<project>
-+ <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
name="Debug">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension"
id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference
id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider-reference
id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider
class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin"
console="false" env-hash="1253352314297216180"
id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorCygwin"
keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings
Cygwin" parameter="${COMMAND} ${FLAGS} -E -P -v -dD
"${INPUTS}"" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+ <configuration
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
name="Release">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension"
id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference
id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider-reference
id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider
class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector"
console="false" env-hash="-910044784883564564"
id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector"
keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler
Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD
"${INPUTS}"" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+</project>
-diff --git a/.settings/org.eclipse.cdt.codan.core.prefs
b/.settings/org.eclipse.cdt.codan.core.prefs
-new file mode 100755
-index 000000000000..b5248c620107
---- /dev/null
-+++ .settings/org.eclipse.cdt.codan.core.prefs
-@@ -0,0 +1,71 @@
-+eclipse.preferences.version=1
-+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
-+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
return\\")",implicit\=>false}
-+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
-+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
return value\\")"}
-+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
-+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting
comments\\")"}
-+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
-+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line
comments\\")"}
-+org.eclipse.cdt.codan.checkers.noreturn=Error
-+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
return value\\")",implicit\=>false}
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract
class cannot be instantiated\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous
problem\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment
in condition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment
to itself\\")"}
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
break at end of case\\")",no_break_comment\=>"no
break",last_case_param\=>false,empty_case_param\=>false}
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching
by reference is recommended\\")",unknown\=>false,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular
inheritance\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class
members should be properly initialized\\")",skip\=>true}
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
arguments\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
template argument\\")"}
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label
statement not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member
declaration not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name
convention for
function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class
has a virtual method and non-virtual destructor\\")"}
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
overload\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
redeclaration\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
redefinition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return
with parenthesis\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format
String Vulnerability\\")"}
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement
has no effect\\")",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested
parenthesis around expression\\")",paramNot\=>false}
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious
semicolon\\")",else\=>false,afterelse\=>false}
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
function declaration\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
static function\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
variable declaration in file
scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol
is not resolved\\")"}
-diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
-new file mode 100755
-index 000000000000..8ec9fe72ca59
---- /dev/null
-+++ .settings/org.eclipse.cdt.core.prefs
-@@ -0,0 +1,6 @@
-+eclipse.preferences.version=1
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/delimiter=;
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/operation=replace
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/value=C\:\\WINDOWS\\system32;C\:\\WINDOWS;C\:\\Program
Files\\SlikSvn\\bin;C\:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0;c\:\\cygwin\\bin;D\:\\develop\\workspaces\\c1\\amigaos-cross-toolchain\\m68k-amigaos\\bin
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/append=true
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/appendContributed=true
-diff --git a/.settings/org.eclipse.core.runtime.prefs
b/.settings/org.eclipse.core.runtime.prefs
-new file mode 100755
-index 000000000000..12511e62a174
---- /dev/null
-+++ .settings/org.eclipse.core.runtime.prefs
-@@ -0,0 +1,5 @@
-+content-types/enabled=true
-+content-types/org.eclipse.cdt.core.cHeader/file-extensions=def
-+content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=h
-+content-types/org.eclipse.cdt.core.cxxSource/file-extensions=c
-+eclipse.preferences.version=1
-diff --git a/config.sub b/config.sub
-index 41146e11c6c9..35247fe0c474 100755
---- config.sub
-+++ config.sub
-@@ -2,7 +2,7 @@
- # Configuration validation subroutine script.
- # Copyright 1992-2016 Free Software Foundation, Inc.
-
--timestamp='2016-01-01'
-+timestamp='2017-04-21'
-
- # This file is free software; you can redistribute it and/or modify it
- # under the terms of the GNU General Public License as published by
-@@ -500,7 +500,7 @@ case $basic_machine in
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
-- amigaos | amigados)
-+ amigaos | amigaosvasm | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
-@@ -1380,7 +1380,7 @@ case $os in
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-+ | -clix* | -riscos* | -uniplus* | -iris* | -rt* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 51e2bc86e9a4..4aedf54bab12 100644
---- gcc/Makefile.in
-+++ gcc/Makefile.in
-@@ -1199,6 +1199,7 @@ OBJS = \
- auto-inc-dec.o \
- auto-profile.o \
- bb-reorder.o \
-+ bbb-opts.o \
- bitmap.o \
- bt-load.o \
- builtins.o \
-@@ -1986,7 +1987,7 @@ gcc-nm.c: gcc-ar.c
- cp $^ $@
-
- COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \
-- collect-utils.o file-find.o hash-table.o
-+ collect-utils.o file-find.o hash-table.o $(EXTRA_COLLECT2_OBJS)
- COLLECT2_LIBS = @COLLECT2_LIBS@
- collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
- # Don't try modifying collect2 (aka ld) in place--it might be linking this.
-@@ -3270,7 +3271,7 @@ endif
- install-strip: install
-
- # Handle cpp installation.
--install-cpp: installdirs cpp$(exeext)
-+install-cpp: installdirs cpp$(exeext) all.cross
- -if test "$(enable_as_accelerator)" != "yes" ; then \
- rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext)
$(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
-diff --git a/gcc/amigacollect2.c b/gcc/amigacollect2.c
-new file mode 100755
-index 000000000000..941ea0248fbe
---- /dev/null
-+++ gcc/amigacollect2.c
-@@ -0,0 +1,348 @@
-+/* GG-local whole file: dynamic libraries */
-+/* Supplimentary functions that get compiled and linked to collect2 for
-+ AmigaOS target.
-+ Copyright (C) 1996 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+
-+/* From collect2.c: */
-+
-+void maybe_unlink(const char *);
-+void fatal_error(location_t, const char *, ...);
-+void fork_execute(const char *, char **, bool);
-+
-+extern char *c_file_name;
-+extern int debug;
-+
-+/* Local functions. */
-+
-+static void safename (char *);
-+static void add_lib (const char *);
-+static void cat (const char *, FILE *);
-+
-+/* Names of temporary files we create. */
-+#define XLIBS_C_NAME "xlibs.c"
-+#define XLIBS_O_NAME "xlibs.o"
-+#define SHARED_X_NAME "shared.x"
-+
-+/* Suffix which is prepended to "-l" options for dynamic libraries. */
-+#define DYNAMIC_LIB_SUFFIX "_ixlibrary"
-+
-+/* Structure that holds library names. */
-+struct liblist
-+{
-+ struct liblist *next;
-+ char *name;
-+ char *cname;
-+};
-+
-+/* Not zero if "-static" was specified on GCC command line or if all the
-+ libraries are static. */
-+static int flag_static=0;
-+
-+/* Not zero if linking a base relative executable. This is recognized by
-+ presence of "-m amiga_bss" on the linker's commandline. */
-+static int flag_baserel=0;
-+
-+/* Not zero if some of the specified libraries are dynamic. */
-+static int found_dynamic_libs=0;
-+
-+/* List of linker libraries. */
-+struct liblist *head = NULL;
-+
-+/* Return 1 if collect2 should do something more apart from tlink. We want it
-+ to call "postlink" and "strip" if linking with dynamic libraries.
*/
-+
-+int
-+amigaos_do_collecting (void)
-+{
-+ return !flag_static;
-+}
-+
-+/* Check for presence of "-static" on the GCC command line. We should not do
-+ collecting if this flag was specified. */
-+
-+void
-+amigaos_gccopts_hook (const char *arg)
-+{
-+ if (strncmp(arg, "-static", strlen("-static"))==0)
-+ flag_static=1;
-+}
-+
-+/* Replace unprintable characters with underscores. Used by "add_lib()". */
-+
-+static void
-+safename (char *p)
-+{
-+ if (!ISALPHA(*p))
-+ *p = '_';
-+ p++;
-+ while (*p)
-+ {
-+ if (!ISALNUM(*p))
-+ *p = '_';
-+ p++;
-+ }
-+}
-+
-+/* Add a library to the list of dynamic libraries. First make sure that the
-+ library is actually dynamic. Used by "amigaos_libname_hook()". */
-+
-+static void
-+add_lib (const char *name)
-+{
-+ struct liblist *lib;
-+ static char buf[256];
-+
-+ for (lib = head; lib; lib = lib->next)
-+ if (!strcmp(lib->name, name))
-+ return;
-+
-+ /* A2IXDIR_PREFIX is passed by "make". */
-+ sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", name);
-+ if (access(buf, R_OK))
-+ return;
-+
-+ lib = (struct liblist*)xmalloc(sizeof(struct liblist));
-+ lib->name = xstrdup(name);
-+ lib->cname = xstrdup(name);
-+ safename(lib->cname);
-+ lib->next = head;
-+ head = lib;
-+
-+ if (debug)
-+ fprintf(stderr, "found dynamic library, name: %s, cname: %s\n",
lib->name,
-+ lib->cname);
-+
-+ found_dynamic_libs=1;
-+}
-+
-+/* Check if the argument is a linker library. Call "add_lib()" if yes. */
-+
-+void
-+amigaos_libname_hook (const char *arg)
-+{
-+ int len = strlen(arg);
-+ if (flag_static)
-+ return;
-+
-+ if (len > 2 && !memcmp(arg, "-l", 2))
-+ add_lib(arg + 2);
-+ else if (len > 2 && !strcmp(arg + len - 2, ".a"))
-+ {
-+ const char *lib;
-+
-+ ((char*)arg)[len - 2] = '\0';
-+ lib = strrchr(arg, '/');
-+ if (lib == NULL)
-+ lib = strrchr(arg, ':');
-+ if (lib == NULL)
-+ lib = arg - 1;
-+ if (!strncmp(lib + 1, "lib", 3))
-+ add_lib(lib + 4);
-+ ((char *)arg)[len - 2] = '.';
-+ }
-+}
-+
-+/* Delete temporary files. */
-+
-+void
-+amigaos_collect2_cleanup (void)
-+{
-+ if (flag_static)
-+ return;
-+ maybe_unlink(XLIBS_C_NAME);
-+ maybe_unlink(XLIBS_O_NAME);
-+ maybe_unlink(SHARED_X_NAME);
-+}
-+
-+/* Copy file named by FNAME to X. */
-+
-+static void
-+cat (const char *fname, FILE *x)
-+{
-+#define BUFSIZE 16384
-+ FILE *in;
-+ static char buf[BUFSIZE];
-+ int bytes;
-+
-+ in = fopen(fname, "r");
-+ if (in == NULL)
-+ fatal_error (input_location, "%s", fname);
-+ while (!feof(in) && (bytes = fread(buf, 1, BUFSIZE, in)))
-+ fwrite(buf, 1, bytes, x);
-+ fclose(in);
-+}
-+
-+/* If no dynamic libraries were found, perform like "-static". Otherwise,
-+ create "xlibs.c", "shared.x" and invoke "gcc" to create
"xlibs.o". We also
-+ have to adjust the linker commandline. */
-+
-+void
-+amigaos_prelink_hook (const char **ld1_argv, int *strip_flag)
-+{
-+ if (flag_static)
-+ return;
-+
-+ if (!found_dynamic_libs)
-+ {
-+ flag_static=1;
-+ /* If the user has not requested "-static", but has requested
"-s",
-+ collect2 removes "-s" from the "ld1_argv", and calls
"strip" after
-+ linking. However, this would not be efficient if we linked the
-+ executable without any dynamic library. In this case, we put "-s"
-+ back. */
-+ if (*strip_flag)
-+ {
-+ /* Add "-s" as the last argument on the command line. */
-+ while (*ld1_argv)
-+ ld1_argv++;
-+ *ld1_argv++="-s";
-+ *ld1_argv=0;
-+ *strip_flag=0;
-+ }
-+ }
-+ else
-+ {
-+ FILE *x, *out;
-+ struct liblist *lib;
-+ static const char* argv[]={0, "-c", XLIBS_C_NAME, 0};
-+ const char **ld1_end, **ld1;
-+
-+ /* Prepend suffixes to dynamic lib names. In addition, check if we are
-+ linking a base relative executable. */
-+ for (ld1=ld1_argv; *ld1; ld1++)
-+ {
-+ int len=strlen(*ld1);
-+ if (strncmp(*ld1, "-l", strlen("-l"))==0)
-+ {
-+ for (lib=head; lib; lib=lib->next)
-+ if (strcmp(*ld1+strlen("-l"), lib->name)==0)
-+ {
-+ char *newname=(char*)
-+ xmalloc(strlen(*ld1)+strlen(DYNAMIC_LIB_SUFFIX)+1);
-+ strcpy(newname, *ld1);
-+ strcat(newname, DYNAMIC_LIB_SUFFIX);
-+ *ld1=newname;
-+ break;
-+ }
-+ }
-+ else if (len > 2 && !strcmp(*ld1 + len - 2, ".a"))
-+ {
-+ const char *libname;
-+ int substituted=0;
-+
-+ ((char *)(*ld1))[len - 2] = '\0';
-+ libname = strrchr(*ld1, '/');
-+ if (libname == NULL)
-+ libname = strrchr(*ld1, ':');
-+ if (libname == NULL)
-+ libname = *ld1 - 1;
-+ if (!strncmp(libname + 1, "lib", 3))
-+ for (lib=head; lib; lib=lib->next)
-+ if (strcmp(libname+4, lib->name)==0)
-+ {
-+ char *newname=(char*)xmalloc(strlen(*ld1)+
-+ strlen(DYNAMIC_LIB_SUFFIX)+3);
-+ strcpy(newname, *ld1);
-+ strcat(newname, DYNAMIC_LIB_SUFFIX);
-+ strcat(newname, ".a");
-+ *ld1=newname;
-+ substituted=1;
-+ break;
-+ }
-+ if (!substituted)
-+ ((char *)(*ld1))[len - 2] = '.';
-+ }
-+ else if (strcmp(ld1[0], "-m")==0 && ld1[1]
-+ && strcmp(ld1[1], "amiga_bss")==0)
-+ {
-+ flag_baserel=1;
-+ break;
-+ }
-+ }
-+
-+ out = fopen(XLIBS_C_NAME, "w");
-+ if (out == NULL)
-+ fatal_error (input_location, "%s", XLIBS_C_NAME);
-+ x = fopen(SHARED_X_NAME, "w");
-+ if (x == NULL)
-+ fatal_error (input_location, "%s", SHARED_X_NAME);
-+
-+ cat((flag_baserel ? A2IXDIR_PREFIX "/amiga_exe_baserel_script.x"
-+ : A2IXDIR_PREFIX "/amiga_exe_script.x"), x);
-+ for (lib = head; lib; lib = lib->next)
-+ {
-+ static char buf[256];
-+ sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", lib->name);
-+ fprintf(out, "extern long %sBase; long *__p%sBase = &%sBase;\n",
-+ lib->cname, lib->cname, lib->cname);
-+ cat(buf, x);
-+ } /* {{ */
-+ fprintf(x, "}}\n");
-+ fclose(out);
-+ fclose(x);
-+ argv[0]=c_file_name;
-+ fork_execute("gcc", (char **)argv, false);
-+
-+ /* Unfortunately, unlike "-s", "-T" cannot be specified as the
last
-+ argument. We put it after "-L" args. */
-+ ld1_end=ld1_argv;
-+ while (*ld1_end)
-+ ld1_end++;
-+ ld1_end++;
-+ /* "ld1_end" now points after the terminating 0 of "ld1_argv".
*/
-+
-+ ld1=ld1_end-2;
-+ while (ld1>ld1_argv && strncmp(*ld1, "-L",
strlen("-L")))
-+ ld1--;
-+ if (ld1==ld1_argv)
-+ fatal_error (input_location, "no -L arguments");
-+ ld1++;
-+ /* "ld1" now points after "-L". */
-+
-+ /* Shift all the arguments after "-L" one position right. */
-+ memmove(ld1+1, ld1, (ld1_end-ld1)*sizeof(*ld1));
-+ /* Put -Tshared.x in the now empty space. */
-+ *ld1="-T" SHARED_X_NAME;
-+ }
-+}
-+
-+/* Be lazy and just call "postlink". */
-+
-+void
-+amigaos_postlink_hook (const char *output_file)
-+{
-+ static const char *argv[]={"postlink", 0, 0, 0};
-+ if (flag_static)
-+ return;
-+
-+ if (flag_baserel)
-+ {
-+ argv[1]="-baserel";
-+ argv[2]=output_file;
-+ }
-+ else
-+ argv[1]=output_file;
-+ fork_execute("postlink", (char **)argv, false);
-+}
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-new file mode 100755
-index 000000000000..9e989e9b1ec0
---- /dev/null
-+++ gcc/bbb-opts.c
-@@ -0,0 +1,4705 @@
-+/* Bebbo's Optimizations.
-+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
-+ Copyright (C) 2017 Stefan "Bebbo" Franke.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 3, or (at your option) any later
-+ version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <
http://www.gnu.org/licenses/>. */
-+
-+/**
-+ * SBF (Stefan "Bebbo" Franke):
-+ *
-+ * This pass performs multiple optimizations.
-+ *
-+ * #1 propagate_moves
-+ * check if a->b->a can be moved out of a loop.
-+ *
-+ * #2 strcpy
-+ * check if a temp reg can be eliminated.
-+ *
-+ * #3 const_comp_sub
-+ * convert a compare with int constant into sub statement.
-+ *
-+ * #4 merge_add
-+ * merge adds
-+ *
-+ * #5 elim_dead_assign
-+ * eliminate some dead assignments.
-+ *
-+ * #6 shrink stack frame
-+ * remove push/pop for unused variables
-+ *
-+ * #7 rename register
-+ * rename registers without breaking register parameters, inline asm etc.
-+ *
-+ * Lessons learned:
-+ *
-+ * - do not trust existing code, better delete insns and inster a new one.
-+ * - do not modify insns, create new insns from pattern
-+ * - do not reuse registers, create new reg rtx instances
-+ *
-+ */
-+
-+#include "config.h"
-+#define INCLUDE_VECTOR
-+#define INCLUDE_SET
-+#define INCLUDE_MAP
-+#include "system.h"
-+#include "coretypes.h"
-+#include "backend.h"
-+#include "target.h"
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "insn-config.h"
-+#include "recog.h"
-+#include "cfgrtl.h"
-+#include "emit-rtl.h"
-+#include "tree.h"
-+#include "tree-pass.h"
-+#include "conditions.h"
-+#include "langhooks.h"
-+#include <vector>
-+#include <set>
-+#include <map>
-+
-+int be_very_verbose;
-+bool be_verbose;
-+
-+extern struct lang_hooks lang_hooks;
-+
-+static void
-+update_insn_infos (void);
-+static unsigned
-+track_regs ();
-+
-+/* Lookup of the current function name. */
-+extern tree current_function_decl;
-+static tree last_function_decl;
-+static char fxname[512];
-+static char const *
-+get_current_function_name ()
-+{
-+ if (current_function_decl == NULL)
-+ strcpy (fxname, "<toplevel>");
-+ else
-+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
-+ return fxname;
-+}
-+
-+/* a simple log to stdout. */
-+static int
-+log (char const * fmt, ...)
-+{
-+ if (!be_verbose)
-+ return 0;
-+
-+ va_list args;
-+ va_start(args, fmt);
-+ if (last_function_decl != current_function_decl)
-+ {
-+ last_function_decl = current_function_decl;
-+ printf (":bbb: in '%s'\n", get_current_function_name ());
-+ }
-+ printf (":bbb: ");
-+ int retval = vprintf (fmt, args);
-+ va_end(args);
-+ fflush (stdout);
-+ return retval;
-+}
-+
-+enum proepis
-+{
-+ IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
-+};
-+
-+/**
-+ * What's needed to track values?
-+ */
-+class track_var
-+{
-+ rtx value[FIRST_PSEUDO_REGISTER];
-+ unsigned mask[FIRST_PSEUDO_REGISTER];
-+
-+ bool
-+ extend (rtx * z, unsigned * mask, machine_mode dstMode, rtx x)
-+ {
-+ switch (GET_CODE(x))
-+ {
-+ case CONST_INT:
-+ case CONST_FIXED:
-+ case CONST_DOUBLE:
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ {
-+ rtx v = value[REGNO(x)];
-+ unsigned mr = mask[REGNO(x)];
-+ /* try to expand the register. */
-+ if (v)
-+ {
-+ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1
<< FIRST_PSEUDO_REGISTER)))
-+ return false;
-+
-+ *mask |= mr;
-+ *z = v;
-+ return true;
-+ }
-+
-+ /* store the reg otherwise. */
-+ *mask |= (1 << REGNO(x));
-+ if (GET_MODE(x) == dstMode)
-+ *z = x;
-+ else
-+ *z = gen_rtx_REG (dstMode, REGNO(x));
-+ return true;
-+ }
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(x, 0);
-+ if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF &&
amiga_is_const_pic_ref (y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant
offset (later).
-+ *z = gen_rtx_PLUS(GET_MODE(x), y, XEXP(x, 1));
-+ else
-+ *z = gen_rtx_MINUS(GET_MODE(x), y, XEXP(x, 1));
-+ return true;
-+ }
-+
-+ /* memory reads. */
-+ case MEM:
-+ {
-+ rtx m = XEXP(x, 0);
-+ switch (GET_CODE(m))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ if (!extend (&m, mask, dstMode, m))
-+ return false;
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(m, 0);
-+ if (!REG_P(y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF
&& amiga_is_const_pic_ref (y))
-+ return false;
-+
-+ if (REG_P(y))
-+ if (!extend (&y, mask, dstMode, y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant
offset (later).
-+ m = gen_rtx_PLUS(GET_MODE(m), y, XEXP(m, 1));
-+ else
-+ m = gen_rtx_MINUS(GET_MODE(m), y, XEXP(m, 1));
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+ }
-+ default:
-+ return false;
-+ }
-+ break;
-+ }
-+ default:
-+ return false;
-+ }
-+ }
-+
-+public:
-+ track_var (track_var const * o = 0)
-+ {
-+ if (o)
-+ assign (o);
-+ else
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+
-+ int
-+ find_alias (rtx src)
-+ {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend (&z, &m, GET_MODE(src), src))
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ // do not alias small int value from -128 ... 127
-+ if (rtx_equal_p (z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z)
> 127 || INTVAL(z) < -128))
-+ return i;
-+ }
-+ }
-+ return -1;
-+ }
-+ void
-+ invalidate_mem (rtx dst)
-+ {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend (&z, &m, GET_MODE(dst), dst))
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (rtx_equal_p (z, value[i]))
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ }
-+ }
-+
-+ rtx
-+ get (unsigned regno)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
-+
-+ return value[regno];
-+ }
-+
-+ void
-+ set (machine_mode mode, unsigned regno, rtx x, unsigned index)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return;
-+
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+
-+ if (!extend (&value[regno], &mask[regno], mode, x))
-+ {
-+ clear (mode, regno, index);
-+ }
-+ }
-+
-+ bool
-+ equals (unsigned regno, rtx x)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ if (x == 0 || value[regno] == 0)
-+ return false;
-+
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (!extend (&z, &m, GET_MODE(x), x))
-+ return false;
-+
-+ return rtx_equal_p (z, value[regno]);
-+ }
-+
-+ void
-+ clear (machine_mode mode, unsigned regno, unsigned index)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return;
-+
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+ value[regno] = gen_rtx_raw_CONST_INT(mode, 0x100000000000000LL | ((long long int )
(regno) << 32) | index);
-+ mask[regno] = 1 << FIRST_PSEUDO_REGISTER;
-+ }
-+
-+ void
-+ clear_aftercall (unsigned index)
-+ {
-+ for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (mask[i] && mask[i] < 1 << FIRST_PSEUDO_REGISTER)
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ clear (SImode, 0, index);
-+ clear (SImode, 1, index);
-+ clear (SImode, 8, index);
-+ clear (SImode, 9, index);
-+ }
-+
-+ void
-+ clear_for_mask (unsigned def, unsigned index)
-+ {
-+ if (!def)
-+ return;
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ // register changed or used somehow
-+ if ((1 << regno) & def)
-+ clear (SImode, regno, index);
-+ }
-+ }
-+
-+ void
-+ assign (track_var const * o)
-+ {
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = o->value[i];
-+ mask[i] = o->mask[i];
-+ }
-+ }
-+
-+ /* only keep common values in both sides. */
-+ void
-+ merge (track_var * o, unsigned)
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ {
-+ value[i] = o->value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ }
-+
-+ /* true if a merge would not change anything. */
-+ bool
-+ no_merge_needed (track_var const * o) const
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ return false;
-+ }
-+ return true;
-+ }
-+};
-+
-+/* Information for each insn to detect alive registers. Enough for m68k.
-+ * Why a class? Maybe extend it for general usage.
-+ *
-+ * Track use & def separate to determine starting points.
-+ */
-+class insn_info
-+{
-+ rtx_insn * insn; // the insn
-+
-+// usage flags
-+ unsigned myuse; // bit set if registers are used in this statement
-+ unsigned hard; // bit set if registers can't be renamed
-+ unsigned use; // bit set if registers are used in program flow
-+ unsigned def; // bit set if registers are defined here
-+
-+ enum proepis proepi;
-+
-+ bool stack; // part of stack frame insns
-+
-+// stuff to analyze insns
-+ bool label;
-+ bool jump;
-+ bool call;
-+ bool compare;
-+ bool dst_mem;
-+ bool src_mem;
-+ bool dst_plus;
-+ bool src_plus;
-+ rtx_code src_op;
-+ bool src_ee;
-+ bool src_2nd;
-+ bool src_const;
-+
-+ machine_mode mode;
-+
-+ rtx dst_reg;
-+ rtx dst_mem_reg;
-+ rtx dst_symbol;
-+ rtx src_reg;
-+ rtx src_mem_reg;
-+ rtx src_symbol;
-+ unsigned dst_mem_addr;
-+ int src_intval;
-+ unsigned src_mem_addr;
-+
-+ bool visited;
-+
-+ int sp_offset;
-+
-+ int dst_autoinc;
-+ int src_autoinc;
-+
-+// values for all variables - if used
-+ track_var * track;
-+
-+public:
-+ insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
-+ insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label
(false), jump (false), call (
-+ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus
(false), src_op (
-+ (rtx_code) 0), src_ee (false), src_2nd (false), src_const (false), mode (VOIDmode),
dst_reg (0), dst_mem_reg (
-+ 0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0),
src_intval (0), src_mem_addr (
-+ 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), track (0)
-+ {
-+ }
-+
-+ track_var *
-+ get_track_var ();
-+
-+ inline ptrdiff_t
-+ operator < (insn_info const & o) const
-+ {
-+ return this - &o;
-+ }
-+
-+ int
-+ get_index () const;
-+
-+ void
-+ plus_to_move (rtx_insn * newinsn);
-+
-+ void
-+ swap_adds (rtx_insn * newinsn, insn_info & ii);
-+
-+ void
-+ absolute2base (unsigned regno, unsigned base, rtx with_symbol);
-+
-+ rtx
-+ make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply);
-+
-+ inline bool
-+ is_compare () const
-+ {
-+ return compare;
-+ }
-+
-+ inline machine_mode
-+ get_mode () const
-+ {
-+ return mode;
-+ }
-+
-+ inline bool
-+ is_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
-+
-+ inline bool
-+ is_dst_mem () const
-+ {
-+ return dst_mem;
-+ }
-+
-+ inline bool
-+ is_src_mem () const
-+ {
-+ return src_mem;
-+ }
-+
-+ inline bool
-+ is_src_mem_2nd () const
-+ {
-+ return src_2nd && src_mem;
-+ }
-+
-+ inline bool
-+ has_dst_memreg () const
-+ {
-+ return dst_mem_reg;
-+ }
-+
-+ inline bool
-+ has_src_memreg () const
-+ {
-+ return src_mem_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_symbol () const
-+ {
-+ return dst_symbol;
-+ }
-+
-+ inline rtx
-+ get_src_symbol () const
-+ {
-+ return src_symbol;
-+ }
-+ inline bool
-+ has_dst_addr () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline bool
-+ has_src_addr () const
-+ {
-+ return src_mem_addr;
-+ }
-+
-+ inline bool
-+ is_label () const
-+ {
-+ return label;
-+ }
-+
-+ inline bool
-+ is_jump () const
-+ {
-+ return jump;
-+ }
-+
-+ inline bool
-+ is_call () const
-+ {
-+ return call;
-+ }
-+
-+ inline unsigned
-+ get_dst_mem_addr () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline unsigned
-+ get_src_mem_addr () const
-+ {
-+ return src_mem_addr;
-+ }
-+
-+ inline bool
-+ is_src_reg () const
-+ {
-+ return src_reg && !src_op;
-+ }
-+
-+ inline int
-+ get_src_op () const
-+ {
-+ return src_op;
-+ }
-+
-+ inline bool
-+ is_src_ee () const
-+ {
-+ return src_ee;
-+ }
-+
-+ inline bool
-+ is_src_mem_plus () const
-+ {
-+ return src_mem && src_plus;
-+ }
-+
-+ inline bool
-+ is_dst_mem_plus () const
-+ {
-+ return dst_mem && dst_plus;
-+ }
-+
-+ inline int
-+ get_dst_regno () const
-+ {
-+ return dst_reg ? REGNO(dst_reg) : -1;
-+ }
-+
-+ inline int
-+ get_src_regno () const
-+ {
-+ return src_reg ? REGNO(src_reg) : -1;
-+ }
-+
-+ inline rtx
-+ get_src_reg () const
-+ {
-+ return src_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
-+
-+ inline int
-+ get_src_mem_regno () const
-+ {
-+ return src_mem_reg ? REGNO(src_mem_reg) : -1;
-+ }
-+
-+ inline int
-+ get_dst_mem_regno () const
-+ {
-+ return dst_mem_reg ? REGNO(dst_mem_reg) : -1;
-+ }
-+
-+ inline rtx
-+ get_src_mem_reg () const
-+ {
-+ return src_mem_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_mem_reg () const
-+ {
-+ return dst_mem_reg;
-+ }
-+
-+ inline int
-+ get_src_intval () const
-+ {
-+ return src_intval;
-+ }
-+
-+ inline int
-+ get_dst_intval () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline bool
-+ is_src_const () const
-+ {
-+ return src_const;
-+ }
-+
-+ inline void
-+ mark_jump ()
-+ {
-+ jump = true;
-+ }
-+ inline void
-+ mark_call ()
-+ {
-+ call = true;
-+ }
-+ inline void
-+ mark_label ()
-+ {
-+ label = true;
-+ }
-+
-+ void
-+ fledder (rtx set);
-+
-+ void
-+ fledder_src_mem (rtx src);
-+
-+ /* update usage. */
-+ void
-+ update (insn_info & o)
-+ {
-+ myuse = o.myuse;
-+ hard = o.hard;
-+ use = o.use;
-+ def = o.def;
-+ }
-+
-+ inline rtx_insn *
-+ get_insn () const
-+ {
-+ return insn;
-+ }
-+
-+ void
-+ mark_stack ()
-+ {
-+ stack = true;
-+ }
-+
-+ bool
-+ is_stack () const
-+ {
-+ return stack;
-+ }
-+
-+ inline enum proepis
-+ in_proepi () const
-+ {
-+ return proepi;
-+ }
-+
-+ inline void
-+ set_proepi (enum proepis p)
-+ {
-+ proepi = p;
-+ }
-+
-+ inline void
-+ reset_flags ()
-+ {
-+ label = false;
-+ jump = false;
-+ compare = false;
-+ dst_mem = false;
-+ src_mem = false;
-+ dst_plus = false;
-+ src_plus = false;
-+ src_op = (rtx_code) 0;
-+ src_ee = false;
-+ src_const = false;
-+
-+ mode = VOIDmode;
-+
-+ dst_reg = 0;
-+ dst_mem_reg = 0;
-+ dst_symbol = 0;
-+ src_reg = 0;
-+ src_mem_reg = 0;
-+ src_symbol = 0;
-+ dst_mem_addr = 0;
-+
-+ src_intval = 0;
-+ src_mem_addr = 0;
-+
-+ dst_autoinc = 0;
-+ src_autoinc = 0;
-+ }
-+
-+ inline int
-+ get_src_autoinc () const
-+ {
-+ return src_autoinc;
-+ }
-+
-+ inline int
-+ get_dst_autoinc () const
-+ {
-+ return dst_autoinc;
-+ }
-+
-+ inline bool
-+ is_empty ()
-+ {
-+ return !def && !use && !hard;
-+ }
-+
-+ inline void
-+ mark_myuse (int regno)
-+ {
-+ myuse |= 1 << regno;
-+ use |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_use (int regno)
-+ {
-+ use |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_def (int regno)
-+ {
-+ def |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_hard (int regno)
-+ {
-+ hard |= 1 << regno;
-+ }
-+
-+ inline void
-+ unset (int regno)
-+ {
-+ use &= ~(1 << regno);
-+ def &= ~(1 << regno);
-+ hard &= ~(1 << regno);
-+ }
-+
-+ inline unsigned
-+ get_use () const
-+ {
-+ return use;
-+ }
-+
-+ inline unsigned
-+ get_myuse () const
-+ {
-+ return myuse;
-+ }
-+
-+ inline void
-+ set_use (unsigned u)
-+ {
-+ use = u;
-+ }
-+
-+ inline unsigned
-+ get_def () const
-+ {
-+ return def;
-+ }
-+ inline unsigned
-+ get_hard () const
-+ {
-+ return hard;
-+ }
-+
-+ inline bool
-+ is_use (int regno)
-+ {
-+ return (use & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_myuse (int regno)
-+ {
-+ return (myuse & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_def (int regno)
-+ {
-+ return (def & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_hard (int regno)
-+ {
-+ return (hard & (1 << regno)) != 0;
-+ }
-+
-+ inline void
-+ clear_hard_def ()
-+ {
-+ hard = 0;
-+ def = 0;
-+ }
-+
-+ /*
-+ * update for previous insn.
-+ * - remove regs which are defined here
-+ * - add regs which are used here
-+ * - reset _def
-+ * - restrain _hard to used
-+ */
-+ inline void
-+ updateWith (insn_info const & o)
-+ {
-+ use &= ~o.def;
-+ use |= o.use;
-+ def = 0;
-+ }
-+
-+ inline insn_info &
-+ merge (insn_info const & o)
-+ {
-+ myuse = o.myuse;
-+ use = (use & ~o.def) | o.use;
-+ def |= o.def;
-+ hard |= o.hard;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ or_use (insn_info const & o)
-+ {
-+ use |= o.myuse | o.def | o.hard;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ drop_def ()
-+ {
-+ use &= ~def;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ make_hard ()
-+ {
-+ hard = use | def;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ make_clobber ()
-+ {
-+ hard = use = def = use | def;
-+ return *this;
-+ }
-+
-+ inline bool
-+ contains (insn_info const & o) const
-+ {
-+ if (o.def & ~def)
-+ return false;
-+ if (o.use & ~use)
-+ return false;
-+ if (o.hard & ~hard)
-+ return false;
-+ return true;
-+ }
-+
-+ inline int
-+ get_sp_offset () const
-+ {
-+ return sp_offset;
-+ }
-+
-+ inline void
-+ set_sp_offset (int sp)
-+ {
-+ sp_offset = sp;
-+ }
-+
-+ inline bool
-+ is_visited () const
-+ {
-+ return visited;
-+ }
-+
-+ inline void
-+ mark_visited ()
-+ {
-+ visited = true;
-+ }
-+
-+ inline void
-+ clear_visited ()
-+ {
-+ visited = false;
-+ }
-+
-+ void
-+ scan ();
-+
-+ void
-+ scan_rtx (rtx);
-+
-+ bool
-+ make_post_inc (int regno);
-+
-+ void
-+ auto_inc_fixup (int regno, int size);
-+
-+ /* return bits for alternate free registers. */
-+ unsigned
-+ get_free_mask () const
-+ {
-+ if (def & hard)
-+ return 0;
-+
-+ if (!def)
-+ return 0;
-+
-+ unsigned def_no_cc = def & ~(1 << FIRST_PSEUDO_REGISTER);
-+ if (def_no_cc > 0x4000)
-+ return 0;
-+
-+ unsigned mask = def_no_cc - 1;
-+ /* more than one register -> don't touch. */
-+ if ((mask & ~def) != mask)
-+ return 0;
-+
-+ if (def_no_cc > 0xff)
-+ mask &= 0xff00;
-+
-+ return mask & ~use;
-+ }
-+
-+ unsigned
-+ get_regbit () const
-+ {
-+ if (GET_MODE_SIZE(mode) > 4)
-+ return 0;
-+ return def & ~hard & ~use & 0x7fff;
-+ }
-+
-+ void
-+ set_insn (rtx_insn * newinsn);
-+
-+ void
-+ a5_to_a7 (rtx a7);
-+};
-+
-+bool
-+insn_info::make_post_inc (int regno)
-+{
-+ rtx pattern = PATTERN (insn);
-+ rtx_insn * new_insn = make_insn_raw (pattern);
-+
-+ // convert into POST_INC
-+ rtx set0 = single_set (new_insn);
-+ if (!set0)
-+ return false;
-+
-+ rtx set = set0;
-+
-+ if (is_compare ())
-+ set = SET_SRC(set);
-+ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+
-+ if (src_op && get_src_mem_regno () == regno)
-+ {
-+ if (src_op == NEG || src_op == NOT || src_op == SIGN_EXTEND)
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-+
-+ rtx reg = XEXP(mem, 0);
-+
-+ XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-+
-+ if (insn_invalid_p (new_insn, 0))
-+ {
-+ XEXP(mem, 0) = reg;
-+ insn_invalid_p (insn, 0);
-+ return 0;
-+ }
-+
-+ SET_INSN_DELETED(insn);
-+ (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-+ insn = emit_insn_after (PATTERN (new_insn), insn);
-+ insn_invalid_p (insn, 0);
-+
-+ return 1;
-+}
-+
-+static rtx
-+add_clobbers (rtx_insn * oldinsn)
-+{
-+ rtx pattern = PATTERN (oldinsn);
-+ if (GET_CODE(pattern) != PARALLEL)
-+ return pattern;
-+
-+ int num_clobbers = 0;
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ ++num_clobbers;
-+ }
-+
-+ if (!num_clobbers)
-+ return pattern;
-+
-+ rtx newpat = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (num_clobbers + 1));
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ XVECEXP(newpat, 0, num_clobbers--) = x;
-+ }
-+
-+ XVECEXP(newpat, 0, 0) = XVECEXP(pattern, 0, 0);
-+ return newpat;
-+}
-+
-+void
-+insn_info::auto_inc_fixup (int regno, int size)
-+{
-+// debug_rtx (insn);
-+ rtx set0 = single_set (insn);
-+ rtx set = set0;
-+ if (is_compare ())
-+ set = SET_SRC(set);
-+
-+ // add to register
-+ if (get_src_regno () == regno)
-+ {
-+ rtx src = SET_SRC(set);
-+ if (get_src_intval () == size)
-+ {
-+ src_intval = 0;
-+ src_plus = false;
-+ SET_SRC(set) = XEXP(src, 0);
-+ }
-+ else
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
-+ }
-+ else if (get_src_mem_regno () == regno)
-+ {
-+ // src mem used ?
-+ rtx mem = SET_SRC(set);
-+ if (src_op)
-+ {
-+ if (MEM_P(XEXP(mem, 0)))
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-+ rtx plus = XEXP(mem, 0);
-+
-+ if (src_mem_addr == (unsigned) size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ src_mem_addr = 0;
-+ src_plus = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), src_mem_addr -= size);
-+ }
-+
-+ if (get_dst_mem_regno () == regno)
-+ {
-+ rtx mem = SET_DEST(set);
-+ rtx plus = XEXP(mem, 0);
-+ if (dst_mem_addr == (unsigned) size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ dst_mem_addr = 0;
-+ dst_plus = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), dst_mem_addr -= size);
-+ }
-+
-+ rtx pattern = add_clobbers (insn);
-+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
-+}
-+
-+track_var *
-+insn_info::get_track_var ()
-+{
-+ if (!track)
-+ track = new track_var ();
-+ return track;
-+}
-+
-+void
-+insn_info::scan ()
-+{
-+ rtx pattern = PATTERN (insn);
-+ if (ANY_RETURN_P(pattern))
-+ {
-+ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-+ int sz = type ? TREE_INT_CST_LOW(type) : 0;
-+ // log ("return size %d\n", sz);
-+ if (sz <= 64)
-+ {
-+ mark_hard (0);
-+ mark_myuse (0);
-+ if (sz > 32)
-+ {
-+ mark_hard (1);
-+ mark_myuse (1);
-+ }
-+ }
-+ }
-+ else if (CALL_P(insn))
-+ {
-+ /* add mregparm registers. */
-+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-+ {
-+ rtx op, reg;
-+
-+ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-+ for (unsigned r = REGNO(reg); r < END_REGNO (reg); ++r)
-+ mark_myuse (r);
-+ }
-+ /* mark scratch registers. */
-+ mark_def (0);
-+ mark_def (1);
-+ mark_def (8);
-+ mark_def (9);
-+ /* also mark all registers as not renamable */
-+ hard = use;
-+ }
-+ scan_rtx (pattern);
-+}
-+
-+/* scan rtx for registers and set the corresponding flags. */
-+void
-+insn_info::scan_rtx (rtx x)
-+{
-+ if (REG_P(x))
-+ {
-+ for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
-+ mark_myuse (r);
-+ return;
-+ }
-+
-+ if (x == cc0_rtx)
-+ {
-+ mark_myuse (FIRST_PSEUDO_REGISTER);
-+ return;
-+ }
-+
-+ RTX_CODE code = GET_CODE(x);
-+
-+ /* handle SET and record use and def. */
-+ if (code == SET)
-+ {
-+ unsigned u = use;
-+ unsigned mu = myuse;
-+ use = myuse = 0;
-+ rtx dst = SET_DEST(x);
-+ scan_rtx (dst);
-+ if (REG_P(dst) || ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
&& REG_P(XEXP(dst, 0))))
-+ {
-+ def |= use;
-+ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG))
-+ use |= u;
-+ else
-+ use = u;
-+ myuse = mu;
-+ }
-+
-+ // avoid side effects from myuse -> def, e.g. adding the dst reg to def by src
auto inc
-+ mu = myuse;
-+ myuse = 0;
-+ scan_rtx (SET_SRC(x));
-+ myuse |= mu;
-+
-+ int code = GET_CODE(SET_SRC(x));
-+ if (code == ASM_OPERANDS)
-+ hard |= def | use;
-+ return;
-+ }
-+
-+ if (code == TRAP_IF)
-+ {
-+ /* mark all registers used. */
-+ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1;
-+ return;
-+ }
-+
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ scan_rtx (XEXP(x, i));
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ {
-+ unsigned u = use;
-+ unsigned mu = myuse;
-+ unsigned d = def;
-+ scan_rtx (XVECEXP(x, i, j));
-+ use |= u;
-+ myuse |= mu;
-+ def |= d;
-+ }
-+ }
-+
-+ if (code == POST_INC || code == PRE_DEC || code == CLOBBER)
-+ def |= myuse;
-+}
-+
-+void
-+insn_info::fledder_src_mem (rtx src)
-+{
-+ src_mem = true;
-+ rtx mem = XEXP(src, 0);
-+
-+ if (GET_CODE(mem) == POST_INC)
-+ src_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ src_autoinc = -1, mem = XEXP(mem, 0);
-+
-+ if (REG_P(mem))
-+ src_mem_reg = mem;
-+ else if (GET_CODE(mem) == CONST_INT)
-+ src_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ src_symbol = mem;
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ src_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ src_mem_reg = reg;
-+ src_const = true;
-+ src_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ src_plus = true;
-+ src_symbol = sym;
-+ src_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
-+}
-+
-+/* read the set and grab infos */
-+void
-+insn_info::fledder (rtx set)
-+{
-+ if (!set || GET_CODE(set) == PARALLEL)
-+ return;
-+
-+ rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
-+
-+ if (dst == cc0_rtx)
-+ {
-+ compare = true;
-+ set = src;
-+ dst = SET_DEST(set);
-+ src = SET_SRC(set);
-+ }
-+
-+ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
-+ dst = XEXP(dst, 0);
-+
-+ mode = GET_MODE(dst);
-+ if (mode == VOIDmode)
-+ mode = GET_MODE(src);
-+
-+ if (REG_P(dst))
-+ {
-+ dst_reg = dst;
-+ }
-+ else if (MEM_P(dst))
-+ {
-+ dst_mem = true;
-+ rtx mem = XEXP(dst, 0);
-+
-+ if (GET_CODE(mem) == POST_INC)
-+ dst_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ dst_autoinc = -1, mem = XEXP(mem, 0);
-+
-+ if (REG_P(mem))
-+ dst_mem_reg = mem;
-+ else if (GET_CODE(mem) == CONST_INT)
-+ dst_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ dst_symbol = mem;
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ dst_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ dst_mem_reg = reg;
-+ dst_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ dst_plus = true;
-+ dst_symbol = sym;
-+ dst_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
-+ }
-+
-+ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
-+ rtx alt_src_reg = 0;
-+ int code = GET_CODE(src);
-+ if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code !=
CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
-+ && code != CONST_FIXED && code != CONST_STRING)
-+ {
-+ src_op = GET_CODE(src);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ if (fmt[0] == 'e' && fmt[1] == 'e')
-+ {
-+ src_ee = true;
-+ rtx operand = XEXP(src, 1);
-+ if (GET_CODE(operand) == CONST_INT || GET_CODE(operand) == CONST_WIDE_INT)
-+ src_const = true, src_intval = INTVAL(operand);
-+ else if (REG_P(operand))
-+ {
-+ alt_src_reg = operand;
-+ }
-+ else if (MEM_P(operand))
-+ {
-+ // it' something like reg = op(reg, mem(...))
-+ src_2nd = true;
-+ fledder_src_mem (operand);
-+ }
-+ }
-+ src = XEXP(src, 0);
-+ }
-+
-+ if (REG_P(src))
-+ {
-+ src_reg = src;
-+ }
-+ else if (MEM_P(src))
-+ {
-+ fledder_src_mem (src);
-+ }
-+ else if (GET_CODE(src) == CONST_INT)
-+ {
-+ src_const = true;
-+ src_intval = INTVAL(src);
-+ }
-+ if (alt_src_reg)
-+ src_reg = alt_src_reg;
-+}
-+
-+/* create a copy for a reg. Optional specify a new register number. */
-+static rtx
-+copy_reg (rtx reg, int newregno)
-+{
-+ if (newregno < 0)
-+ newregno = REGNO(reg);
-+ rtx x = gen_raw_REG (GET_MODE(reg), newregno);
-+ x->jump = reg->jump;
-+ x->call = reg->call;
-+ x->unchanging = reg->unchanging;
-+ x->volatil = reg->volatil;
-+ x->in_struct = reg->in_struct;
-+ x->used = reg->used;
-+ x->frame_related = reg->frame_related;
-+ x->return_val = reg->return_val;
-+
-+ x->u.reg.attrs = reg->u.reg.attrs;
-+ return x;
-+}
-+
-+/* Rename the register plus track all locs to undo these changes. */
-+static rtx
-+find_reg_by_no (rtx x, unsigned oldregno)
-+{
-+ if (!x)
-+ return 0;
-+
-+ RTX_CODE code = GET_CODE(x);
-+
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y))
-+ {
-+ if (REGNO(y) == oldregno)
-+ return y;
-+ }
-+ else
-+ {
-+ rtx r = find_reg_by_no (y, oldregno);
-+ if (r)
-+ return r;
-+ }
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ {
-+ rtx z = XVECEXP(x, i, j);
-+ rtx r = find_reg_by_no (z, oldregno);
-+ if (r)
-+ return r;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Collect some data.
-+ */
-+static std::vector<insn_info> infos;
-+typedef std::vector<insn_info>::iterator insn_info_iterator;
-+
-+// insn->u2.insn_uid -> rtx_insn *
-+static std::multimap<int, rtx_insn *> label2jump;
-+typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
-+
-+// index -> index
-+static std::multimap<unsigned, unsigned> jump2label;
-+typedef std::multimap<unsigned, unsigned>::iterator j2l_iterator;
-+
-+static std::map<rtx_insn *, insn_info *> insn2info;
-+typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-+
-+static std::set<unsigned> scan_starts;
-+typedef std::set<unsigned>::iterator su_iterator;
-+
-+static insn_info * info0;
-+static unsigned usable_regs;
-+
-+static void
-+update_insn2index ()
-+{
-+ infos.reserve (infos.size () * 8 / 7 + 2);
-+ insn2info.clear ();
-+ /* needs a separate pass since the insn_infos require fixed addresses for
->get_index() */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ insn2info.insert (std::make_pair (ii.get_insn (), &ii));
-+ }
-+ info0 = &infos[0];
-+}
-+
-+static void
-+update_label2jump ()
-+{
-+ update_insn2index ();
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.is_label ())
-+ for (l2j_iterator i = label2jump.find (ii.get_insn ()->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
-+ jump2label.insert (std::make_pair (insn2info.find
(i->second)->second->get_index (), index));
-+ }
-+}
-+
-+int
-+insn_info::get_index () const
-+{
-+ insn_info * ii = &infos[0];
-+
-+ if (ii == info0)
-+ {
-+ ptrdiff_t diff = ((char const *) this - (char const *) ii);
-+ unsigned pos = diff / sizeof(insn_info);
-+ if (pos < infos.size ())
-+ return pos;
-+ }
-+
-+// realloc happened...
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ if (infos[i].get_insn () == this->insn)
-+ return i;
-+
-+// whoops!?
-+ return 0;
-+}
-+
-+void
-+insn_info::plus_to_move (rtx_insn * newinsn)
-+{
-+ insn = newinsn;
-+ src_op = (rtx_code) 0;
-+ src_reg = XEXP(PATTERN (newinsn), 1);
-+ insn2info.insert (std::make_pair (insn, this));
-+// usage flags did not change
-+}
-+
-+void
-+insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
-+{
-+ insn = newinsn;
-+
-+ std::swap (*this, ii);
-+
-+ insn2info.insert (std::make_pair (insn, this));
-+ insn2info.insert (std::make_pair (ii.insn, &ii));
-+
-+// usage flags did not change
-+}
-+
-+static
-+void
-+replace_reg (rtx x, unsigned regno, rtx newreg, int offset)
-+{
-+ RTX_CODE code = GET_CODE(x);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y) && REGNO(y) == regno)
-+ {
-+ XEXP(x, i) = newreg;
-+ if (offset && i + 1 < GET_RTX_LENGTH(code))
-+ {
-+ rtx c = XEXP(x, i + 1);
-+ if (GET_CODE(c) == CONST_INT)
-+ XEXP(x, i + 1) = gen_rtx_CONST_INT (GET_MODE(x), INTVAL(c) + offset);
-+ }
-+ }
-+ else
-+ replace_reg (y, regno, newreg, offset);
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ replace_reg (XVECEXP(x, i, j), regno, newreg, offset);
-+ }
-+}
-+
-+void
-+insn_info::a5_to_a7 (rtx a7)
-+{
-+ if (proepi == IN_EPILOGUE && src_mem_reg && get_src_mem_regno () ==
FRAME_POINTER_REGNUM)
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ {
-+ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
-+ return;
-+ }
-+ }
-+ replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4);
-+}
-+
-+void
-+insn_info::set_insn (rtx_insn * newinsn)
-+{
-+ insn = newinsn;
-+
-+ reset_flags ();
-+
-+ fledder (single_set (insn));
-+}
-+
-+rtx
-+insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool
apply)
-+{
-+ rtx set = single_set (get_insn ());
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+ rtx reg = gen_raw_REG (SImode, regno);
-+ bool vola = src->volatil;
-+
-+ if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) &&
!has_dst_memreg () && get_dst_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_dst_mem_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
-+ {
-+ if (base == addr)
-+ dst = gen_rtx_MEM (mode, reg);
-+ else
-+ dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode,
offset)));
-+
-+ if (apply)
-+ {
-+ dst_mem_reg = reg;
-+ dst_mem = true;
-+ dst_mem_addr = offset;
-+ dst_plus = offset != 0;
-+ }
-+ }
-+ }
-+
-+ if (is_src_mem () && (has_src_addr () || get_src_symbol ()) &&
!has_src_memreg () && get_src_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_src_mem_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
-+ {
-+ if (base == addr)
-+ src = gen_rtx_MEM (mode, reg);
-+ else
-+ src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode,
offset)));
-+
-+ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax)
*/
-+ if (src_op)
-+ {
-+ if (src_ee)
-+ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
-+ else
-+ {
-+ if (src_op == SIGN_EXTEND)
-+ {
-+ PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
-+ src->call = 1;
-+ }
-+ src = gen_rtx_fmt_e(src_op, mode, src);
-+ }
-+ }
-+
-+ if (apply)
-+ {
-+ src_mem_reg = reg;
-+ src_mem = true;
-+ src_mem_addr = offset;
-+ src_plus = offset != 0;
-+ }
-+ }
-+ }
-+
-+ rtx pattern = gen_rtx_SET(dst, src);
-+ src->volatil = vola;
-+
-+ return pattern;
-+}
-+
-+void
-+insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-+{
-+ rtx pattern = make_absolute2base (regno, base, with_symbol, true);
-+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
-+
-+ mark_myuse (regno);
-+
-+ insn2info.insert (std::make_pair (insn, this));
-+}
-+/*
-+ * Reset collected data.
-+ */
-+static void
-+clear (void)
-+{
-+ label2jump.clear ();
-+ jump2label.clear ();
-+ insn2info.clear ();
-+ infos.clear ();
-+ scan_starts.clear ();
-+}
-+
-+/*
-+ * return true if the register is DEAD.
-+ * Do not check at jumps.
-+ */
-+static bool
-+is_reg_dead (unsigned regno, unsigned _pos)
-+{
-+// skip labels.
-+ for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
-+ {
-+ insn_info & ii = infos[pos];
-+ // skip entries without info
-+ if (ii.is_empty ())
-+ continue;
-+
-+ // not dead if usage is reported in the next statement
-+ return !ii.is_use (regno) && !ii.is_hard (regno);
-+ }
-+ return true;
-+}
-+
-+bool dump_reg_track;
-+void
-+append_reg_cache (FILE * f, rtx_insn * insn)
-+{
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
-+ return;
-+
-+ insn_info & jj = *i->second;
-+ unsigned index = jj.get_index ();
-+ if (index + 1 < infos.size ())
-+ ++index;
-+ insn_info & ii = infos[index];
-+
-+ track_var * track = ii.get_track_var ();
-+ if (track == 0)
-+ return;
-+
-+ fprintf (f, "\n");
-+
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ rtx v = track->get (regno);
-+ if (v == 0)
-+ continue;
-+
-+// if (GET_CODE(v) == CONST_INT && GET_MODE(v) == VOIDmode)
-+// continue;
-+
-+ fprintf (f, "%s=", reg_names[regno]);
-+
-+ print_inline_rtx (f, v, 12);
-+ fprintf (f, "\n");
-+ }
-+}
-+
-+/* helper stuff to enhance the asm output. */
-+int my_flag_regusage;
-+void
-+append_reg_usage (FILE * f, rtx_insn * insn)
-+{
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
-+ return;
-+
-+ insn_info & ii = *i->second;
-+
-+ if (f != stderr)
-+ {
-+ if (be_very_verbose > 1)
-+ fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
-+ else
-+ fprintf (f, "\n\t\t\t\t\t|\t");
-+ }
-+
-+ fprintf (f, "%c ", ii.in_proepi () == IN_PROLOGUE ? 'p' :
ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-+
-+ for (int j = 0; j < 8; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse
(j) ? "." : " ");
-+ fprintf (f, "d%d ", j);
-+ }
-+ else
-+ fprintf (f, " ");
-+
-+ for (int j = 8; j < 16; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse
(j) ? "." : " ");
-+ fprintf (f, "a%d ", j - 8);
-+ }
-+ else
-+ fprintf (f, " ");
-+
-+ if (ii.is_use (FIRST_PSEUDO_REGISTER))
-+ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc
");
-+ else
-+ fprintf (f, " ");
-+
-+ // append fp usage info if present
-+ if ((ii.get_use () | ii.get_def ()) & ~0xffff)
-+ {
-+ for (int j = 16; j < 24; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" :
ii.is_myuse (j) ? "." : " ");
-+ fprintf (f, "f%d ", j - 16);
-+ }
-+ else
-+ fprintf (f, " ");
-+ }
-+
-+ if (f == stderr)
-+ fprintf (f, "\n");
-+
-+}
-+
-+/*
-+ * Helper function to dump the code.
-+ * Sometimes used during debugging.
-+ */
-+static void
-+dump_insns (char const * name, bool all)
-+{
-+ fprintf (stderr, "====================================: %s\n", name);
-+ if (all)
-+ {
-+ for (rtx_insn * insn = get_insns (); insn && insn != infos[0].get_insn ();
insn = NEXT_INSN (insn))
-+ debug_rtx (insn);
-+ }
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ fprintf (stderr, "%d: ", i);
-+
-+ rtx_insn * insn = infos[i].get_insn ();
-+ if (i < infos.size ())
-+ append_reg_usage (stderr, insn);
-+
-+ fprintf (stderr, "\t");
-+ debug_rtx (insn);
-+
-+ if (all)
-+ {
-+ rtx_insn * p = i + 1 < infos.size () ? infos[i + 1].get_insn () : 0;
-+ for (rtx_insn * q = NEXT_INSN (insn); q && q != p; q = NEXT_INSN (q))
-+ debug_rtx (q);
-+ }
-+ }
-+}
-+
-+/* This is the important function to track register usage plus hard/live state.
-+ *
-+ * Start at bottom and work upwards. On all labels trigger all jumps referring to this
label.
-+ * A set destination into a register is a def. All other register references are an
use.
-+ * Hard registers cann't be renamed and are mandatory for regparms and
asm_operands.
-+ */
-+static void
-+update_insn_infos (void)
-+{
-+ /* add all return (jump outs) and start analysis there. */
-+ std::set<unsigned> & todo = scan_starts;
-+
-+ if (todo.begin () == todo.end ())
-+ todo.insert (infos.size () - 1);
-+
-+ bool locka4 = flag_pic >= 3;
-+
-+ while (!todo.empty ())
-+ {
-+ int start = *todo.begin ();
-+ todo.erase (todo.begin ());
-+ insn_info ii = infos[start];
-+
-+ enum proepis proepi = ii.in_proepi ();
-+
-+ // mark sp reg as used.
-+ if (proepi >= IN_EPILOGUE)
-+ ii.mark_use (STACK_POINTER_REGNUM), infos[start].mark_use (STACK_POINTER_REGNUM);
-+
-+ for (int pos = start; pos >= 0; --pos)
-+ {
-+ insn_info & pp = infos[pos];
-+ rtx_insn * insn = pp.get_insn ();
-+
-+ // do not run into previous epilogue
-+ if (pp.in_proepi () >= IN_EPILOGUE && !proepi)
-+ break;
-+
-+ proepi = pp.in_proepi ();
-+
-+ /* no new information -> break. */
-+ if (pos != start && pp.is_visited () && !JUMP_P(insn) &&
pp.contains (ii))
-+ break;
-+
-+ ii.clear_hard_def ();
-+ ii.merge (pp);
-+
-+ if (LABEL_P(insn))
-+ {
-+ /* work on all jumps referring to that label. */
-+ l2j_iterator i = label2jump.find (insn->u2.insn_uid);
-+
-+ /* no jump to here -> mark all registers as hard regs.
-+ * This label is maybe used in an exception handler.
-+ * Marking as hard also avoids stack frame removal.
-+ */
-+ if (i == label2jump.end ())
-+ infos[pos + 1].make_hard ();
-+ else
-+ for (l2j_iterator k = i; i != label2jump.end () && i->first == k->first;
++i)
-+ {
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j != insn2info.end ())
-+ {
-+ unsigned index = j->second->get_index ();
-+ insn_info & jj = infos[index];
-+ if (!jj.is_visited () || !jj.contains (ii))
-+ {
-+ jj.updateWith (ii);
-+ todo.insert (index);
-+ }
-+ }
-+ }
-+
-+ if (pos == start)
-+ pp.mark_visited ();
-+
-+ /* check previous insn for jump */
-+ if (pos > 0 && infos[pos - 1].is_jump ())
-+ {
-+ rtx_insn * prev = infos[pos - 1].get_insn ();
-+ rtx set = single_set (prev);
-+ /* unconditional? -> break! */
-+ if (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE)
-+ break;
-+ }
-+
-+ continue;
-+ }
-+
-+ pp.mark_visited ();
-+
-+ rtx pattern = PATTERN (insn);
-+ insn_info use (insn);
-+ use.scan ();
-+ if (locka4 && (use.get_myuse () & (1 << PIC_REG)))
-+ use.mark_hard (PIC_REG);
-+
-+ /* do not mark a node as visited, if it's in epilogue and not yet visited. */
-+ if (CALL_P(insn) || JUMP_P(insn))
-+ {
-+ if (pos != start && ii.in_proepi ())
-+ {
-+ su_iterator k = scan_starts.find (pos);
-+ if (k != scan_starts.end ())
-+ {
-+ pp.clear_visited ();
-+ break;
-+ }
-+ }
-+ }
-+ else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
-+ {
-+ use.make_clobber ();
-+ }
-+ else if (single_set (insn) == 0)
-+ use.make_hard ();
-+ else
-+ /* if not cc0 defined check for mod. */
-+ if (!use.is_def (FIRST_PSEUDO_REGISTER))
-+ {
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn), insn);
-+ if (cc_status.value1 || cc_status.value2)
-+ use.mark_def (FIRST_PSEUDO_REGISTER);
-+ }
-+
-+ // TODO: use 2 bits for data regs, to indicate mode size
-+// // also check mode size if < 4, it's also a use for data registers.
-+// if (pp.get_dst_reg () && pp.get_dst_regno () < 8 &&
GET_MODE_SIZE(pp.get_mode()) < 4)
-+// use.mark_use (pp.get_dst_regno ());
-+
-+ /* mark not renameable in prologue/epilogue. */
-+ if (pp.in_proepi () != IN_CODE)
-+ use.make_hard ();
-+
-+ ii.merge (use);
-+ pp.update (ii);
-+ ii.updateWith (use);
-+ }
-+ }
-+
-+ /* fill the mask of general used regs. */
-+ insn_info zz;
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (ii.in_proepi () != IN_PROLOGUE)
-+ break;
-+
-+ zz.or_use (ii);
-+ }
-+
-+ /* always allow a0/a1, d0/d1. */
-+ usable_regs = zz.get_use () | 0x303;
-+ if (flag_pic)
-+ usable_regs &= ~(1 << PIC_REG);
-+
-+ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM))
-+ usable_regs &= ~(1 << FRAME_POINTER_REGNUM);
-+
-+ usable_regs &= ~(1 << STACK_POINTER_REGNUM);
-+}
-+
-+enum AbortCodes
-+{
-+ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL, E_SP_MISMATCH
-+};
-+
-+/*
-+ * Create a filtered view of insns - keep only those to work with.
-+ */
-+static unsigned
-+update_insns ()
-+{
-+ rtx_insn *insn, *next;
-+ unsigned result = 0;
-+ rtx jump_table = 0;
-+
-+ clear ();
-+
-+ enum proepis inproepilogue = IN_PROLOGUE;
-+ /* create a vector with relevant insn. */
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
-+ {
-+
-+ infos.push_back (insn_info (insn, inproepilogue));
-+ insn_info & ii = infos[infos.size () - 1];
-+
-+ if (JUMP_P(insn))
-+ {
-+ if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
-+ {
-+ if (ANY_RETURN_P(PATTERN (insn)))
-+ ii.set_proepi (IN_EPILOGUE);
-+
-+ scan_starts.insert (infos.size () - 1);
-+ inproepilogue = IN_CODE;
-+ rtx set = single_set (insn);
-+ if (ANY_RETURN_P(PATTERN (insn))
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE))
-+ continue;
-+ }
-+
-+ ii.mark_jump ();
-+ if (jump_table)
-+ {
-+ if (XEXP(jump_table, 0) != insn)
-+ {
-+ if (be_very_verbose)
-+ {
-+ debug_rtx (insn);
-+ debug_rtx (jump_table);
-+ }
-+ result = E_JUMP_TABLE_MISMATCH;
-+ jump_table = 0;
-+ continue;
-+ }
-+
-+ // -> jump_table_data
-+ rtx table = PATTERN (XEXP(jump_table, 1));
-+ if (GET_CODE(table) == ADDR_DIFF_VEC || GET_CODE(table) == ADDR_VEC)
-+ {
-+ int k = GET_CODE(table) == ADDR_DIFF_VEC;
-+ for (int j = 0; j < XVECLEN(table, k); ++j)
-+ {
-+ rtx ref = XVECEXP(table, k, j);
-+ if (!LABEL_REF_NONLOCAL_P(ref))
-+ {
-+ rtx label = XEXP(ref, 0);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ ii.set_proepi (IN_EPILOGUE);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ if (be_very_verbose)
-+ {
-+ debug_rtx (insn);
-+ debug_rtx (jump_table);
-+ }
-+ result = E_JUMP_GOTO_LABEL;
-+ jump_table = 0;
-+ continue;
-+ }
-+ jump_table = 0;
-+ }
-+ else
-+ {
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (!label)
-+ {
-+ if (be_very_verbose)
-+ debug_rtx (insn);
-+ result = E_NO_JUMP_LABEL;
-+ continue;
-+ }
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
-+ }
-+ else if (LABEL_P(insn))
-+ {
-+ ii.mark_label ();
-+ jump_table = 0;
-+ ii.set_proepi (inproepilogue = IN_CODE);
-+ if (infos.size () > 1)
-+ scan_starts.insert (infos.size () - 1);
-+ }
-+ else if (CALL_P(insn))
-+ {
-+ if (insn->jump)
-+ {
-+ ii.set_proepi (IN_EPILOGUE);
-+ ii.mark_jump ();
-+ scan_starts.insert (infos.size () - 1);
-+ }
-+ ii.mark_call ();
-+ if (inproepilogue)
-+ {
-+ scan_starts.insert (infos.size () - 1);
-+ inproepilogue = IN_CODE;
-+ }
-+ }
-+ else
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ ii.fledder (set);
-+
-+ for (rtx next, note = REG_NOTES(insn); note; note = next)
-+ {
-+ next = XEXP(note, 1);
-+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND)
-+ {
-+ jump_table = XEXP(note, 0);
-+ }
-+ }
-+
-+ }
-+ }
-+ else if (NOTE_P(insn))
-+ {
-+ if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-+ inproepilogue = IN_CODE;
-+ else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-+ inproepilogue = IN_EPILOGUE;
-+ }
-+ }
-+ scan_starts.insert (infos.size () - 1);
-+ update_insn2index ();
-+ update_insn_infos ();
-+
-+ return result;
-+}
-+
-+/* convert the lowest set bit into a register number. */
-+static int
-+bit2regno (unsigned bit)
-+{
-+ if (!bit)
-+ return -1;
-+
-+ unsigned regno = 0;
-+ while (!(bit & 1))
-+ {
-+ ++regno;
-+ bit >>= 1;
-+ }
-+ return regno;
-+}
-+
-+/* check if that register is touched between from and to, excluding from and to .*/
-+static bool
-+is_reg_touched_between (unsigned regno, int from, int to)
-+{
-+ for (int index = from + 1; index < to; ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.is_myuse (regno) || ii.is_def (regno))
-+ return true;
-+ }
-+ return false;
-+}
-+
-+/*
-+ * search backward and find the initial assignment for that regno.
-+ */
-+static unsigned
-+find_start (unsigned start, unsigned rename_regno)
-+{
-+ /* search the start. */
-+ while (start > 0)
-+ {
-+ unsigned startm1 = start - 1;
-+
-+ /* do not run over RETURNS */
-+ insn_info & jj = infos[start];
-+
-+ /* stop at labels. If a label is a start pos, a search is maybe started again. */
-+ if (jj.is_label ())
-+ break;
-+
-+ insn_info & bb = infos[startm1];
-+ if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
-+ break;
-+
-+ /* found the definition without use. */
-+ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
-+ break;
-+
-+ start = startm1;
-+ }
-+ return start;
-+}
-+
-+/*
-+ * Always prefer lower register numbers within the class.
-+ */
-+static unsigned
-+opt_reg_rename (void)
-+{
-+ update_label2jump ();
-+// dump_insns ("rename", 1);
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ /* do not rename if register is hard or used in same statement. */
-+ const unsigned rename_regbit = ii.get_regbit ();
-+ if (!rename_regbit)
-+ continue;
-+
-+ const unsigned rename_regno = bit2regno (rename_regbit);
-+
-+ /* get the mask for free registers. */
-+ unsigned mask = ii.get_free_mask ();
-+
-+ /* the mask contains the current src register. Add this register to the mask if
it's dead here. */
-+ if (ii.get_src_reg () && is_reg_dead (ii.get_src_regno (), index))
-+ mask |= ii.get_use ();
-+
-+ /* do not use a4 if compiling baserel */
-+ if (flag_pic >= 3)
-+ mask &= ~(1 << PIC_REG);
-+
-+ if (!mask)
-+ continue;
-+
-+ /* first = pos to start, second indicates to treat def as use. */
-+ std::set<unsigned> todo;
-+ std::set<unsigned> found;
-+ if (index + 1 < infos.size ())
-+ todo.insert (index + 1);
-+
-+ found.insert (index);
-+ /* a register was defined, follow all branches. */
-+ while (mask && todo.begin () != todo.end ())
-+ {
-+ unsigned runpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-+
-+// printf ("runpos %d \n", runpos); fflush (stdout);
-+ for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
-+ {
-+ /* already searched. */
-+ if (found.find (pos) != found.end ())
-+ break;
-+
-+ rtx_insn * insn = infos[pos].get_insn ();
-+ if (LABEL_P(insn))
-+ {
-+ found.insert (pos);
-+
-+ /* for each jump to this label:
-+ * check if the reg was used at that jump.
-+ * if used, find def
-+ */
-+ for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
-+ {
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j == insn2info.end ())
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ unsigned startat = j->second->get_index ();
-+ if (found.find (startat) != found.end () || !infos[startat].is_use
(rename_regno))
-+ continue;
-+
-+ unsigned start = find_start (startat, rename_regno);
-+// printf ("label %d <- jump %d : start %d\n", pos, startat, start);
fflush (stdout);
-+ todo.insert (start);
-+ }
-+
-+ /* if this label is at a start, check if it is reachable from the previous insn,
-+ * and if, check for use then search start. */
-+ if (pos > 0)
-+ {
-+ insn_info & bb = infos[pos - 1];
-+ rtx set = single_set (bb.get_insn ());
-+ if (ANY_RETURN_P(bb.get_insn ())
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE))
-+ continue;
-+
-+// printf ("label start check %d use %d\n", pos, bb.is_use
(rename_regno) || bb.is_def(rename_regno)); fflush (stdout);
-+
-+ if (bb.is_use (rename_regno) || bb.is_def (rename_regno))
-+ {
-+ unsigned start = find_start (pos - 1, rename_regno);
-+ todo.insert (start);
-+// printf ("label %d : start %d \n", pos, start); fflush (stdout);
-+ }
-+ }
-+
-+ continue;
-+ }
-+
-+ insn_info & jj = infos[pos];
-+
-+ /* marked as hard reg -> invalid rename */
-+ if (jj.get_use () & jj.get_hard () & rename_regbit)
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ /* not used. and not a def */
-+ if (pos == runpos && (jj.get_def () & rename_regbit))
-+ {
-+ /* continue since this pos was added by start search. */
-+ }
-+ else if (!(jj.get_use () & rename_regbit))
-+ break;
-+
-+ /* abort if some insn using this reg uses more than 1 reg. */
-+ if ((jj.get_myuse () & rename_regbit) && GET_MODE_SIZE(jj.get_mode())
> 4)
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ /* update free regs. */
-+ mask &= ~jj.get_use ();
-+ mask &= ~jj.get_def ();
-+ if (!mask)
-+ break;
-+
-+ found.insert (pos);
-+
-+ /* follow jump and/or next insn. */
-+ if (JUMP_P(insn))
-+ {
-+ for (j2l_iterator i = jump2label.find (pos), k = i; i != jump2label.end ()
&& i->first == k->first;
-+ ++i)
-+ {
-+ unsigned label_index = i->second;
-+
-+ /* add the label to the search list. */
-+ insn_info & bb = infos[label_index + 1];
-+ if (found.find (label_index) == found.end () && bb.is_use
(rename_regno))
-+ {
-+// printf ("jump %d -> label %d \n", pos, label_index); fflush
(stdout);
-+ todo.insert (label_index);
-+ }
-+ }
-+ rtx set = single_set (insn);
-+ if (!set)
-+ {
-+ // it's a parallel pattern - search the set pc = ...
-+ rtx pat = PATTERN (insn);
-+ for (int j = XVECLEN (pat, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pat, 0, j);
-+ if (XEXP(x, 0) == pc_rtx)
-+ {
-+ set = x;
-+ break;
-+ }
-+ }
-+ }
-+ rtx jmpsrc = set ? SET_SRC(set) : 0;
-+ if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (mask)
-+ {
-+ int oldregno = bit2regno (rename_regbit);
-+ int newregno = bit2regno (mask);
-+
-+ /* check the renamed insns. */
-+ std::vector<unsigned> positions;
-+ for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-+ {
-+ insn_info & rr = infos[*i];
-+ rtx_insn * insn = rr.get_insn ();
-+
-+ /* get rename locations. */
-+ rtx from = find_reg_by_no (PATTERN (insn), oldregno);
-+ if (from)
-+ {
-+ rtx to = gen_raw_REG (GET_MODE(from), newregno);
-+ validate_replace_rtx_group (from, to, insn);
-+
-+ positions.push_back (*i);
-+ }
-+ }
-+
-+ if (!apply_change_group ())
-+ continue;
-+
-+ log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n",
reg_names[oldregno], reg_names[newregno],
-+ positions.size (), index);
-+
-+ if (be_verbose)
-+ {
-+ for (std::vector<unsigned>::iterator i = positions.begin (); i !=
positions.end (); ++i)
-+ printf ("%d ", *i);
-+ printf ("\n");
-+ fflush (stdout);
-+ }
-+
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * #1 propagate a->b->a moves out of a loop.
-+ *
-+ * consider a loop:
-+ *
-+ * .L1
-+ * ...
-+ * move d0, a0 ; (1)
-+ * ...
-+ * move xy, (a0)+
-+ * ...
-+ * move a0, d0 ; (2)
-+ * ...
-+ * jxx .L1
-+ *
-+ * Then the statements (1) and (2) can be moved out of the loop:
-+ *
-+ * move d0, a0 ; (3)
-+ * .L1
-+ * ...
-+ * move *, (a0)+ ; a0 is modified somehow
-+ * ...
-+ * jxx .L1
-+ * move a0, d0 ; (4)
-+ *
-+ * if all criteria are met:
-+ *
-+ * a) no other jump to .L1 -> (LABEL_NUSES(insn) == 1)
-+ * b) no other use of d0 inside the loop
-+ * c) no other use of a0 before (1)
-+ * d) no other use of a1 after (2)
-+ *
-+ * Optional:
-+ * - omit (4) if d0 is dead
-+ *
-+ * this will e.g. convert
-+ .L6:
-+ move.l d0,a1
-+ move.b (a1)+,d1
-+ move.l a1,d0
-+ move.b d1,(a0)+
-+ cmp.b #0, d1
-+ jne .L6
-+ * to
-+ move.l d0,a1
-+ .L6:
-+ move.b (a1)+,d1
-+ move.b d1,(a0)+
-+ cmp.b #0, d1
-+ jne .L6
-+
-+ *
-+ * Also allow exit jumps, if the modification of the reg is const
-+ * and insert a correction after the exit label.
-+ * The label must only be reachable by the exit jump.
-+ */
-+static unsigned
-+opt_propagate_moves ()
-+{
-+ unsigned change_count = 0;
-+ rtx_insn * current_label = 0;
-+ unsigned current_label_index;
-+ std::vector<unsigned> reg_reg;
-+ std::vector<rtx_insn *> jump_out;
-+
-+ /* start at 1 since there must be an insn before the label. */
-+ for (unsigned index = 1; index < infos.size (); ++index)
-+ {
-+ rtx_insn * insn = infos[index].get_insn ();
-+
-+ if (LABEL_P(insn))
-+ {
-+ if (LABEL_NUSES(insn) == 1)
-+ {
-+ current_label = insn;
-+ current_label_index = index;
-+ reg_reg.clear ();
-+ jump_out.clear ();
-+ }
-+ else
-+ current_label = 0;
-+ }
-+
-+ if (current_label == 0)
-+ continue;
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ // check for set reg, reg
-+ rtx set = single_set (insn);
-+ if (set)
-+ {
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+ if (REG_P(src) && REG_P(dst))
-+ reg_reg.push_back (index);
-+ }
-+ else
-+ current_label = 0;
-+
-+ continue;
-+ }
-+
-+ if (JUMP_P(insn))
-+ {
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (label != current_label)
-+ {
-+ /* collect the labels for a later check if a fixup is possible. */
-+ if (LABEL_NUSES(label) == 1 && BARRIER_P(PREV_INSN (label)))
-+ jump_out.push_back (label);
-+ else
-+ current_label = 0;
-+ continue;
-+ }
-+
-+ if (reg_reg.size () > 1)
-+ {
-+ /* Search for reg/reg pairs. */
-+ for (std::vector<unsigned>::iterator i = reg_reg.begin (); i != reg_reg.end
() && i + 1 != reg_reg.end ();
-+ )
-+ {
-+ bool inc = true;
-+ for (std::vector<unsigned>::iterator j = i + 1; j != reg_reg.end ();)
-+ {
-+ rtx_insn * ii = infos[*i].get_insn ();
-+ rtx seti = single_set (ii);
-+ rtx srci = SET_SRC(seti);
-+ rtx dsti = SET_DEST(seti);
-+ rtx_insn * jj = infos[*j].get_insn ();
-+ rtx setj = single_set (jj);
-+ rtx srcj = SET_SRC(setj);
-+ rtx dstj = SET_DEST(setj);
-+
-+ if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti))
-+ {
-+ /* Ensure correct usage. */
-+ if (is_reg_touched_between (REGNO(srci), current_label_index, *i) // label ... move
src,x
-+ || is_reg_touched_between (REGNO(srci), *i, *j) // move src,x ... move x,src
-+ || is_reg_touched_between (REGNO(srci), *j, index) // move x,src ... jcc
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // label ... move src,x
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // move x,src ... jcc
-+ )
-+ {
-+ ++j;
-+ continue;
-+ }
-+
-+ std::vector<int> fixups;
-+
-+ /* if there are jumps out of the loop,
-+ * check if the modification occurs before the jump,
-+ * and if, that it's a plus const.
-+ */
-+ if (jump_out.size ())
-+ {
-+ std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
-+ int fixup = 0;
-+
-+ for (unsigned k = *i + 1; k != *j; ++k)
-+ {
-+ rtx_insn * check = infos[k].get_insn ();
-+ if (JUMP_P(check))
-+ {
-+ fixups.push_back (fixup);
-+ if (++label_iter == jump_out.end ())
-+ break;
-+ continue;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
-+ {
-+ /* right now only support auto_incs. */
-+ rtx set = single_set (check);
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+
-+ if (reg_overlap_mentioned_p (dsti, dst))
-+ {
-+ if (REG_P(dst))
-+ break;
-+ if (!MEM_P(dst))
-+ break;
-+
-+ rtx x = XEXP(dst, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, src))
-+ {
-+ if (REG_P(src))
-+ fixup += 0;
-+ else
-+ {
-+ if (!MEM_P(src))
-+ break;
-+
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* got a fixup for all jump_outs? */
-+ if (fixups.size () == jump_out.size ())
-+ {
-+ rtx_insn * before = infos[current_label_index - 1].get_insn ();
-+ rtx_insn * after = infos[index + 1].get_insn ();
-+ rtx bset = single_set (before);
-+
-+ log ("(p) propagate_moves condition met, moving regs %s, %s\n",
-+ reg_names[REGNO(srci)],
-+ reg_names[REGNO(dsti)]);
-+
-+ /* Move in front of loop and mark as dead. */
-+ rtx_insn * newii = make_insn_raw (PATTERN (ii));
-+ SET_INSN_DELETED(ii);
-+
-+ /* Plus check if the reg was just loaded. */
-+ if (bset)
-+ {
-+ rtx bdst = SET_DEST(bset);
-+ if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
-+ {
-+ SET_SRC(PATTERN(newii)) = SET_SRC(bset);
-+// SET_INSN_DELETED(ii);
-+ }
-+ }
-+ else
-+ add_reg_note (newii, REG_DEAD, srci);
-+
-+ add_insn_after (newii, before, 0);
-+
-+ /* Move behind loop - into next BB. */
-+ rtx_insn * newjj = make_insn_raw (PATTERN (jj));
-+ add_insn_before (newjj, after, 0);
-+ SET_INSN_DELETED(jj);
-+
-+ reg_reg.erase (j);
-+ reg_reg.erase (i);
-+ j = reg_reg.end ();
-+ inc = false;
-+
-+ /* add fixes if there were jumps out of the loop. */
-+ if (jump_out.size ())
-+ {
-+ log ("(p) propagate_moves fixing %d jump outs\n", jump_out.size ());
-+
-+ for (unsigned k = 0; k < jump_out.size (); ++k)
-+ {
-+ rtx neu = gen_rtx_SET(
-+ dstj, gen_rtx_PLUS (Pmode, dsti, gen_rtx_CONST_INT (Pmode, fixups[k])));
-+ emit_insn_after (neu, jump_out[k]);
-+ }
-+ }
-+ ++change_count;
-+ }
-+ }
-+ if (inc)
-+ ++j;
-+ }
-+ if (inc)
-+ ++i;
-+ }
-+ }
-+ current_label = 0;
-+ }
-+ }
-+ return change_count;
-+}
-+
-+/**
-+ * Search for
-+ *
-+ * mov x,reg
-+ * mov reg,x
-+ * cmp #0, reg
-+ * jxx
-+ *
-+ * patterns.
-+ *
-+ * Use a simple state machine to find the patterns.
-+ */
-+static unsigned
-+opt_strcpy ()
-+{
-+ unsigned change_count = 0;
-+#if HAVE_cc0
-+ rtx_insn * x2reg = 0;
-+ rtx_insn * reg2x;
-+ unsigned int regno;
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ rtx_insn * insn = infos[index].get_insn ();
-+
-+ if (!NONJUMP_INSN_P(insn))
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-+
-+ rtx set = single_set (insn);
-+ if (!set)
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-+
-+ if (x2reg && reg2x)
-+ {
-+ rtx src = SET_SRC(set);
-+ if (GET_CODE(src) == COMPARE)
-+ {
-+ rtx dst = XEXP(src, 0);
-+ src = XEXP(src, 1);
-+
-+// if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note
(insn, REG_DEAD, dst))
-+ if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 &&
is_reg_dead (REGNO(dst), index))
-+ {
-+ /* now check via NOTICE_UPDATE_CC*/
-+ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-+ if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
-+ {
-+ rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set
(x2reg)));
-+ rtx_insn * newinsn = make_insn_raw (pattern);
-+
-+ if (!insn_invalid_p (newinsn, 0))
-+ {
-+ log ("(s) opt_strcpy condition met, removing compare and joining insns - omit
reg %s\n",
-+ reg_names[REGNO(dst)]);
-+
-+ SET_INSN_DELETED(x2reg);
-+ SET_INSN_DELETED(reg2x);
-+ SET_INSN_DELETED(insn);
-+
-+ insn = emit_insn_after (pattern, reg2x);
-+ insn_invalid_p (insn, 0);
-+
-+ ++change_count;
-+ }
-+ }
-+ }
-+ x2reg = 0;
-+ continue;
-+ }
-+ reg2x = 0;
-+ }
-+
-+ /* check for reg2x first, maybe fallback to x2reg. */
-+ if (x2reg && reg2x == 0)
-+ {
-+ if (REG_P(SET_SRC(set)) && REGNO(SET_SRC(set)) == regno)
-+ {
-+ reg2x = insn;
-+ continue;
-+ }
-+ x2reg = 0;
-+ }
-+
-+ /* check for a match for x2reg. */
-+ if (x2reg == 0)
-+ {
-+ if (REG_P(SET_DEST(set)))
-+ {
-+ x2reg = insn;
-+ reg2x = 0;
-+ regno = REGNO(SET_DEST(set));
-+ }
-+ }
-+ }
-+#endif
-+ return change_count;
-+}
-+
-+/*
-+ * convert
-+ *
-+ * set reg1, plus (reg2, const)
-+ * set mem(reg2), y
-+ *
-+ * ->
-+ * set reg1, reg2
-+ * set mem(reg1+), y
-+ *
-+ * if size of postinc == const
-+ *
-+ (insn 33 32 35 4 (set (reg/v/f:SI 8 a0 [orig:47 s ] [47])
-+ (plus:SI (reg/v/f:SI 9 a1 [orig:46 s ] [46])
-+ (const_int 1 [0x1]))) sn.c:5 141 {*addsi3_internal}
-+ (nil))
-+ (insn 36 35 37 4 (set (mem:QI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) [0 MEM[base: s_17,
offset: 4294967295B]+0 S1 A8])
-+ (mem:QI (post_inc:SI (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])) [0 MEM[base: s2_19, offset:
4294967295B]+0 S1 A8])) sn.c:5 46 {*m68k.md:1083}
-+ (expr_list:REG_INC (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])
-+ (nil)))
-+ */
-+static unsigned
-+opt_commute_add_move (void)
-+{
-+ unsigned change_count = 0;
-+
-+ for (unsigned index = 0; index + 1 < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.get_dst_regno () < 8 || ii.get_dst_regno () > 15 || ii.get_src_op ()
!= PLUS
-+ || ii.get_src_regno () == ii.get_dst_regno () || !ii.get_src_intval ())
-+ continue;
-+
-+ insn_info & jj = infos[index + 1];
-+
-+ if (!jj.get_dst_mem_reg () || jj.get_dst_mem_regno () != ii.get_src_regno ()
-+ || jj.get_src_regno () == ii.get_dst_regno () || GET_MODE_SIZE(jj.get_mode()) !=
ii.get_src_intval ())
-+ continue;
-+
-+ rtx_insn * insn = ii.get_insn ();
-+
-+ rtx_insn * next = jj.get_insn ();
-+ rtx set2 = single_set (next);
-+ rtx dst = SET_DEST(set2);
-+ if (!MEM_P(dst))
-+ continue;
-+
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg ());
-+ rtx newmem = replace_equiv_address_nv (dst, pinc);
-+
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg (), ii.get_src_reg
()));
-+
-+ if (!insn_invalid_p (newinsn, 1) && validate_change (next,
&SET_DEST(set2), newmem, 1) && apply_change_group ())
-+ {
-+ log ("(a) commute_add_move found\n");
-+
-+ SET_INSN_DELETED(insn);
-+
-+ insn = emit_insn_before (newinsn, next);
-+
-+ add_reg_note (next, REG_INC, ii.get_dst_reg ());
-+
-+ ++change_count;
-+ }
-+ else
-+ cancel_changes (0);
-+ }
-+ return change_count;
-+}
-+
-+/*
-+ * Replace
-+ *
-+ * move x,dx
-+ * cmp dx,dy
-+ *
-+ * if dx and dy are both dead after compare.
-+ *
-+ * with
-+ *
-+ * sub #n,dx
-+ *
-+ d0 d1 d2 a0 a1 a7 (insn 99 59 41 7 (set (reg:SI 2 d2)
-+ (const_int 1 [0x1])) sn.c:8 38 {*movsi_m68k}
-+ (nil))
-+ d0 d1 d2 a0 a1 a7 (insn 41 99 42 7 (set (cc0)
-+ (compare (reg/v:SI 1 d1 [orig:54 n ] [54])
-+ (reg:SI 2 d2))) sn.c:8 16 {*m68k.md:499}
-+ (expr_list:REG_DEAD (reg:SI 2 d2)
-+ (expr_list:REG_DEAD (reg/v:SI 1 d1 [orig:54 n ] [54])
-+ (nil))))
-+ *
-+ */
-+static unsigned
-+opt_const_cmp_to_sub (void)
-+{
-+ unsigned change_count = 0;
-+#if HAVE_cc0
-+ if (infos.size () < 2)
-+ return change_count;
-+
-+ unsigned lastsub = 0;
-+ for (unsigned index = infos.size () - 2; index > 0; --index)
-+ {
-+ insn_info & i1 = infos[index];
-+
-+ /* we wan't a compare or tst insn, */
-+ if (!i1.is_compare ())
-+ continue;
-+
-+ if (GET_MODE_SIZE(i1.get_mode()) > 4 || !i1.is_dst_reg () ||
REGNO(i1.get_dst_reg()) > 7)
-+ continue;
-+
-+ /* src must be a reg dead register with a constant - or a #0 */
-+ if (!i1.get_src_reg () && (!i1.is_src_const () || i1.get_src_op () ==
PLUS))
-+ continue;
-+
-+ /* allow an alive reg, if life ends at previous handled sub. */
-+ int lastsubval = 0;
-+ if (lastsub == index + 3)
-+ {
-+ insn_info & pp = infos[lastsub];
-+ if (pp.get_dst_regno () != i1.get_dst_regno ())
-+ continue;
-+ lastsubval = pp.get_src_intval ();
-+
-+ // but still check for usage after this jump
-+ j2l_iterator l = jump2label.find (index + 2);
-+ if (l == jump2label.end ())
-+ continue;
-+
-+ insn_info & label = infos[l->second + 1];
-+ if (label.is_use (i1.get_dst_regno ()))
-+ continue;
-+ }
-+ else if (!is_reg_dead (i1.get_dst_regno (), index))
-+ continue;
-+
-+ insn_info & i0 = infos[index - 1];
-+ int intval = 0;
-+ /* compare with register - check previous insn for load with constant. */
-+ if (i1.is_src_reg ())
-+ {
-+ if (!is_reg_dead (i1.get_src_regno (), index))
-+ continue;
-+
-+ if (GET_MODE_SIZE(i0.get_mode()) > 4)
-+ continue;
-+
-+ if (!i0.is_dst_reg () || !i0.is_src_const () || i0.get_src_op ())
-+ continue;
-+
-+ if (i0.get_dst_regno () != i1.get_src_regno ())
-+ continue;
-+
-+ intval = -i0.get_src_intval ();
-+ if (intval < -8 || intval > 7)
-+ continue;
-+
-+ /* is the next sub value in range? */
-+ if (lastsub == index + 3 && (lastsubval - intval < -8 || lastsubval -
intval > 7))
-+ continue;
-+ }
-+
-+ /* next insn must be the jump. */
-+ insn_info & i2 = infos[index + 1];
-+ if (!i2.is_jump ())
-+ continue;
-+
-+ rtx jmppattern = single_set (i2.get_insn ());
-+ if (!jmppattern)
-+ continue;
-+
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ continue;
-+
-+ rtx condition = XEXP(jmpsrc, 0);
-+ RTX_CODE code = GET_CODE(condition);
-+ if (code != EQ && code != NE)
-+ continue;
-+
-+ if (intval)
-+ {
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (),
intval));
-+
-+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-+
-+ if (insn_invalid_p (subinsn, 0))
-+ continue;
-+
-+ /* delete move #x,dy. */
-+ SET_INSN_DELETED(i0.get_insn ())
-+ /* delete cmp dx,dy */
-+ SET_INSN_DELETED(i1.get_insn ());
-+ /* add a cmp #0 - to be removed in final() */
-+
-+ /* convert cmp/tst into sub */
-+ subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
-+ i1.set_insn (subinsn);
-+
-+ rtx neu = gen_rtx_SET(cc0_rtx,
-+ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
-+
-+ emit_insn_before (neu, i2.get_insn ());
-+
-+ log ("(c) const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n",
reg_names[i1.get_dst_regno ()],
-+ reg_names[i0.get_dst_regno ()],
-+ -intval, -intval, reg_names[i1.get_dst_regno ()]);
-+
-+ if (index + 3 == lastsub)
-+ {
-+ /* patch previous sub - or even a compare. */
-+ insn_info & pp = infos[lastsub];
-+
-+ int diff = lastsubval - intval;
-+ rtx c = gen_rtx_CONST_INT (i1.get_mode (), diff);
-+
-+ if (pp.is_compare ())
-+ {
-+ /* still a compare with 0 -> insert the sub. */
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
-+ rtx set = gen_rtx_SET(copyreg, sub);
-+ emit_insn_before (set, pp.get_insn ());
-+ }
-+ else
-+ {
-+ /* modify the sub. */
-+ XEXP(SET_SRC(PATTERN(pp.get_insn())), 1) = c;
-+ }
-+ }
-+
-+ lastsub = index;
-+ ++change_count;
-+ }
-+ }
-+#endif
-+ return change_count;
-+}
-+
-+/*
-+ * rare and only little gain - but :-)
-+ lea (-1,a0),a1
-+ add.l d1,a1
-+ subq.l #1,d1
-+ ->
-+ move.l a0,a1
-+ subq.l #1,d1
-+ add.l d1,a1
-+ */
-+static unsigned
-+opt_merge_add (void)
-+{
-+ unsigned change_count = 0;
-+ for (unsigned index = 0; index + 2 < infos.size (); ++index)
-+ {
-+ insn_info & ii0 = infos[index];
-+ insn_info & ii1 = infos[index + 1];
-+ insn_info & ii2 = infos[index + 2];
-+
-+ if (!ii2.is_dst_reg ())
-+ {
-+ index += 2;
-+ continue;
-+ }
-+
-+ if (!ii1.is_dst_reg ())
-+ {
-+ ++index;
-+ continue;
-+ }
-+
-+ if (!ii0.is_dst_reg () || ii0.get_src_op () != PLUS || ii1.get_src_op () != PLUS
|| ii2.get_src_op () != PLUS)
-+ continue;
-+
-+ if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () !=
ii2.get_src_intval ())
-+ continue;
-+
-+ if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () !=
ii2.get_dst_regno ())
-+ continue;
-+
-+ rtx_insn * insn1 = ii1.get_insn ();
-+
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
-+ if (cc_status.value1 || cc_status.value2)
-+ continue;
-+
-+ log ("(m) %d: merge_add applied\n", index);
-+
-+ rtx_insn * insn0 = ii0.get_insn ();
-+ rtx set = PATTERN (insn0);
-+
-+ // convert lea (-1,a0),a1 into move.l a0,a1
-+ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1),
0)));
-+ add_insn_after (newins0, insn0, 0);
-+ SET_INSN_DELETED(insn0);
-+ // update infos accordingly
-+ ii0.plus_to_move (newins0);
-+
-+ rtx_insn * insn2 = ii2.get_insn ();
-+ rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
-+ add_insn_after (newins1, insn2, 0);
-+ SET_INSN_DELETED(insn1);
-+ ii1.swap_adds (newins1, ii2);
-+
-+ ++change_count;
-+ }
-+ return change_count;
-+}
-+
-+/* Update the insn_infos to 'know' the sp offset. */
-+static unsigned
-+track_sp ()
-+{
-+// reset visited flags - also check if sp is used as REG src.
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+
-+ // if sp is used as source, we cannot shrink the stack yet
-+ // too complicated
-+ if (ii.get_src_regno () == STACK_POINTER_REGNUM)
-+ return -1;
-+ }
-+
-+// add entry point
-+ std::set<unsigned> todo;
-+ todo.insert (0);
-+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-+
-+ int sp_offset = infos[startpos].get_sp_offset ();
-+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () != IN_CODE)
-+ {
-+ ii.set_sp_offset (sp_offset);
-+ continue;
-+ }
-+
-+ // already visited? sp_offset must match
-+ if (ii.is_visited ())
-+ {
-+ if (ii.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
-+ break;
-+ }
-+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.set_sp_offset (sp_offset);
-+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end ()
&& i->first == k->first; ++i)
-+ {
-+ insn_info & ll = infos[i->second];
-+ if (ll.is_visited () && ll.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
-+
-+ ll.set_sp_offset (sp_offset);
-+ todo.insert (i->second);
-+ }
-+ continue;
-+ }
-+
-+ // is sp modified directly
-+ if (ii.is_dst_reg () && ii.get_dst_regno () == STACK_POINTER_REGNUM)
-+ {
-+ // handle sp = sp + const_int
-+ if (!ii.get_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM ||
ii.get_src_op () != PLUS)
-+ return E_SP_MISMATCH;
-+
-+ sp_offset = sp_offset + ii.get_src_intval ();
-+ continue;
-+ }
-+
-+ // handle dst mem autoinc
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM
&& ii.get_dst_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_dst_autoinc ();
-+
-+ // handle src mem autoinc
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM
&& ii.get_src_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_src_autoinc ();
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/* recursive function to patch stack pointer offsets. */
-+void
-+patch_sp (rtx x, int adjust, int spoffset)
-+{
-+ int code = GET_CODE(x);
-+ if (code == PLUS)
-+ {
-+ rtx a = XEXP(x, 0);
-+ rtx b = XEXP(x, 1);
-+ if (REG_P(a) && REGNO(a) == STACK_POINTER_REGNUM && GET_CODE(b) ==
CONST_INT)
-+ {
-+ if (INTVAL(b) > -spoffset)
-+ XEXP(x, 1) = gen_rtx_CONST_INT (GET_MODE(b), INTVAL(b) - adjust);
-+ return;
-+ }
-+ }
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ patch_sp (XEXP(x, i), adjust, spoffset);
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ patch_sp (XVECEXP(x, i, j), adjust, spoffset);
-+ }
-+}
-+
-+/**
-+ * 1. scan for all used registers.
-+ * 2. scan the stack from for omittable push/pop
-+ * 3. adjust stack frame + insns referring to stack pointer
-+ * typical code:
-+ subq.l #4,sp
-+ movem.l #16190,-(sp)
-+ move.l 52(sp),d2
-+ move.l 56(sp),d3
-+
-+ * or
-+ link a5,#4
-+ movem.l #16190,-(sp)
-+ move.l 8(a5),d2
-+ move.l 12(a5),d3
-+ *
-+ * => with a5 check only prolog/epilog
-+ * => without a5 adjust insns referring sp if offset > startoffset + current sp
diff
-+ *
-+ * startvalue count(pushes)*4
-+ * newstartvalue = startvalue - omitted pushes
-+ */
-+static unsigned
-+opt_shrink_stack_frame (void)
-+{
-+ /* nothing to do. */
-+ if (!infos.size ())
-+ return 0;
-+
-+ /* needed to track sp correctly. */
-+ update_label2jump ();
-+ if (track_sp ())
-+ return 0; // do nothing on stack errors
-+
-+ std::vector<int> a5pos;
-+
-+ unsigned pos = 0;
-+ rtx_insn * insn = infos[pos].get_insn ();
-+ if (JUMP_P(insn)) /* return -> empty function*/
-+ return 0;
-+
-+ bool usea5 = false;
-+ int paramstart = 4;
-+ int a5offset = 0;
-+
-+ /*
-+ * Move prologue to temp.
-+ * Only register push and parallel insn unless its a link a5 are moved.
-+ */
-+ for (; pos < infos.size ();)
-+ {
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-+
-+ if (ii.in_proepi () != IN_PROLOGUE)
-+ break;
-+
-+ rtx pattern = PATTERN (insn);
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
-+ /* ignore link a5 */
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ {
-+ a5pos.push_back (pos);
-+ usea5 = true;
-+ set = XVECEXP(pattern, 0, 2);
-+ a5offset = INTVAL(XEXP(SET_SRC(set), 1));
-+ }
-+ ++pos;
-+ continue;
-+ }
-+ if (GET_CODE(pattern) != SET)
-+ {
-+ /* (set (mem:BLK (scratch) [0 A8]) (unspec:BLK [ ...)) */
-+ if (MEM_P(SET_DEST(pattern)) && GET_CODE(SET_SRC(pattern)) == UNSPEC)
-+ a5pos.push_back (pos);
-+ ++pos;
-+ continue;
-+ }
-+
-+ /* move only the push statements. */
-+ rtx src = SET_SRC(pattern);
-+ rtx dest = SET_DEST(pattern);
-+ if (REG_P(src))
-+ {
-+ if (MEM_P(dest))
-+ {
-+ rtx predec = XEXP(dest, 0);
-+ if (GET_CODE(predec) == PRE_DEC)
-+ {
-+ rtx reg = XEXP(predec, 0);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
-+ {
-+ ii.mark_stack ();
-+ }
-+ }
-+ }
-+ }
-+ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) ==
STACK_POINTER_REGNUM)
-+ {
-+ /* check for stack variables. */
-+ rtx reg = XEXP(src, 0);
-+ rtx cx = XEXP(src, 1);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM &&
CONST_INT_P(cx))
-+ paramstart -= INTVAL(cx);
-+ }
-+
-+ if (++pos >= infos.size ())
-+ {
-+ return 0;
-+ }
-+ }
-+
-+ if (pos == 0)
-+ return 0;
-+
-+ unsigned prologueend = pos;
-+
-+ /* search epilogues - there can be multiple epilogues. */
-+ while (pos < infos.size ())
-+ {
-+ while (pos < infos.size ())
-+ {
-+ if (infos[pos].in_proepi () != IN_CODE)
-+ break;
-+ ++pos;
-+ }
-+
-+ /* move epilogues away. */
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-+ if (JUMP_P(insn) || LABEL_P(insn) || ii.in_proepi () == IN_CODE)
-+ break;
-+
-+ /* omit the frame pointer a5. */
-+ rtx pattern = PATTERN (insn);
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
-+ /* unlink is last. */
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ {
-+ a5pos.push_back (pos);
-+ break;
-+ }
-+
-+ }
-+ else if (GET_CODE(pattern) == SET)
-+ {
-+ /* check for move (a7+), x */
-+ rtx src = SET_SRC(pattern);
-+ rtx dst = SET_DEST(pattern);
-+ if (REG_P(dst))
-+ {
-+ if (MEM_P(src))
-+ {
-+ rtx postinc = XEXP(src, 0);
-+ if (GET_CODE(postinc) == POST_INC)
-+ {
-+ rtx reg = XEXP(postinc, 0);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
-+ ii.mark_stack ();
-+ }
-+ else if (GET_CODE(postinc) == PLUS)
-+ {
-+ rtx a5 = XEXP(postinc, 0);
-+ if (REG_P(a5) && REGNO(a5) == FRAME_POINTER_REGNUM)
-+ ii.mark_stack ();
-+ }
-+ }
-+ }
-+ }
-+ }
-+ ++pos;
-+ }
-+ /* gather usage stats without prologue/epilogue */
-+ insn_info ii;
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & jj = infos[i];
-+ if (jj.in_proepi () != IN_CODE)
-+ continue;
-+
-+ ii.or_use (jj);
-+ }
-+ unsigned freemask = ~ii.get_use () & 0x7fff;
-+
-+ rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
-+ rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
-+
-+ unsigned changed = 0;
-+ unsigned adjust = 0;
-+ unsigned regs_seen = 0;
-+ unsigned regs_total_size = 0;
-+ /* now all push/pop insns are in temp. */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (!ii.is_stack ())
-+ continue;
-+
-+ insn = ii.get_insn ();
-+ rtx pattern = PATTERN (insn);
-+ /* check the pushed regs, either a vector or single statements */
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ // do not touch the frame pointer parallel insn.
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ continue;
-+
-+ if (ii.in_proepi () == IN_EPILOGUE)
-+ ii.set_proepi (IN_EPILOGUE_PARALLEL_POP);
-+
-+ regs_seen = 0;
-+ regs_total_size = 0;
-+ std::vector<rtx> regs;
-+ std::vector<rtx> clobbers;
-+ for (int j = 0; j < XVECLEN(pattern, 0); ++j)
-+ {
-+ rtx set = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(set) == CLOBBER)
-+ {
-+ clobbers.push_back (set);
-+ continue;
-+ }
-+ rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
-+ rtx reg;
-+ if (MEM_P(src))
-+ reg = dst;
-+ else if (MEM_P(dst))
-+ reg = src;
-+ else
-+ continue;
-+
-+ if (i < prologueend)
-+ paramstart += 4;
-+ unsigned regbit = 1 << REGNO(reg);
-+
-+ ++regs_seen;
-+ if (freemask & regbit)
-+ {
-+ log (i < prologueend ? "(f) remove push for %s\n" : "(f) remove
pop for %s\n",
-+ reg_names[REGNO(reg)]);
-+ if (i < prologueend)
-+ adjust += GET_MODE_SIZE(GET_MODE(reg));
-+ }
-+ else
-+ {
-+ regs_total_size += GET_MODE_SIZE(GET_MODE(reg));
-+ regs.push_back (copy_reg (reg, -1));
-+ }
-+ }
-+
-+ /* add room for add.
-+ * push is always using -(a7) addressing.
-+ * If a5 is used a movem offset(a5) is generated to pop saved registers..
-+ * Otherwise a7 is used and with (a7)+ addressing.
-+ */
-+ int add1 = i < prologueend || !usea5 ? 1 : 0;
-+ if (regs.size () < regs_seen)
-+ {
-+ log ("(f) shrinking stack frame from %d to %d\n", regs_seen, regs.size
());
-+ if (regs.size () <= 2)
-+ {
-+ changed = 1;
-+ for (unsigned k = 0; k < regs.size (); ++k)
-+ {
-+ rtx reg = regs[k];
-+ if (i < prologueend)
-+ {
-+ /* push */
-+ rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
dec);
-+ rtx set = gen_rtx_SET(mem, reg);
-+ emit_insn_after (set, insn);
-+ }
-+ else
-+ {
-+ /* pop */
-+ rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
dec);
-+ rtx set = gen_rtx_SET(reg, mem);
-+ emit_insn_before (set, insn);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 +
clobbers.size ()));
-+ rtx plus;
-+
-+ int x = 0;
-+ for (unsigned k = 0; k < regs.size (); ++k)
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+
-+ unsigned l = 0;
-+ /* no add if a5 is used with pop */
-+ if (add1)
-+ {
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ?
-x : x));
-+ XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
-+ ++l;
-+ }
-+
-+ if (i >= prologueend)
-+ x = usea5 ? -x : 0;
-+
-+ for (unsigned k = 0; k < regs.size (); ++k, ++l)
-+ {
-+ if (i < prologueend)
-+ {
-+ /* push */
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-+ x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
plus);
-+ rtx set = gen_rtx_SET(mem, regs[k]);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ else
-+ {
-+ /* pop */
-+ if (usea5)
-+ {
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ else
-+ {
-+ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ }
-+ }
-+
-+ for (unsigned k = 0; k < clobbers.size (); ++k, ++l)
-+ {
-+ rtx clobber = clobbers[k];
-+ XVECEXP(parallel, 0, l) = clobber;
-+ }
-+
-+ rtx_insn * neu;
-+ if (i < prologueend)
-+ neu = emit_insn_after (parallel, insn);
-+ else
-+ neu = emit_insn_before (parallel, insn);
-+ ii.set_insn (neu);
-+ }
-+ SET_INSN_DELETED(insn);
-+ changed = 1;
-+ }
-+ }
-+ else
-+ {
-+ rtx set = PATTERN (insn);
-+
-+ if (i < prologueend)
-+ {
-+ /* move x,-(a7). */
-+ rtx src = SET_SRC(set);
-+ paramstart += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-+ unsigned regbit = 1 << REGNO(src);
-+ if (freemask & regbit)
-+ {
-+ adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-+ log ("(f) remove push for %s\n", reg_names[REGNO(src)]);
-+ SET_INSN_DELETED(insn);
-+ ++changed;
-+ }
-+ }
-+ else
-+ {
-+ /* move (a7)+,x */
-+ rtx dst = SET_DEST(set);
-+ unsigned regbit = 1 << REGNO(dst);
-+ if (freemask & regbit)
-+ {
-+ log ("(f) remove pop for %s\n", reg_names[REGNO(dst)]);
-+ SET_INSN_DELETED(insn);
-+ ++changed;
-+ }
-+ }
-+ }
-+ }
-+
-+ /* fix sp offsets. */
-+ if (!usea5 && adjust)
-+ {
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () != IN_CODE)
-+ continue;
-+
-+ rtx pattern = single_set (ii.get_insn ());
-+ if (pattern)
-+ patch_sp (pattern, adjust, ii.get_sp_offset ());
-+ }
-+ }
-+
-+ if (usea5 && a5offset == -4)
-+ {
-+ /* for now only drop the frame pointer if it's not used.
-+ * Needs tracking of the sp to adjust the offsets.
-+ */
-+ if (freemask & (1 << FRAME_POINTER_REGNUM))
-+ {
-+ log ("(f) dropping unused frame pointer\n");
-+ for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend
(); ++i)
-+ {
-+ int index = *i;
-+ SET_INSN_DELETED(infos[index].get_insn ());
-+
-+ // move to last insn in epilogue
-+ while (index - 1 > 0 && infos[index - 1].in_proepi () >=
IN_EPILOGUE)
-+ --index;
-+
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
-+ {
-+ log ("(f) adjusting exit sp\n");
-+ rtx pattern = gen_rtx_SET(
-+ a7, gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -ii.get_sp_offset
())));
-+ emit_insn_before (pattern, ii.get_insn ());
-+ }
-+ }
-+
-+ /* convert all parameter accesses via a5 into a7. */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (ii.get_myuse () & (1 << FRAME_POINTER_REGNUM))
-+ {
-+ ii.a5_to_a7 (a7);
-+ if (regs_seen && ii.in_proepi () == IN_EPILOGUE_PARALLEL_POP)
-+ {
-+ // exit sp insn needs an +
-+ rtx pattern = PATTERN (ii.get_insn ());
-+ unsigned sz = XVECLEN(pattern, 0);
-+
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
-+ unsigned n = 0;
-+ for (unsigned j = 0; j < sz; ++j)
-+ {
-+ rtx set = XVECEXP(pattern, 0, j);
-+ rtx reg = SET_DEST(set);
-+ rtx mem = SET_SRC(set);
-+ rtx plus = XEXP(mem, 0);
-+ if (n)
-+ {
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n);
-+ }
-+ else
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ }
-+ n += GET_MODE_SIZE(GET_MODE(reg));
-+ XVECEXP(parallel, 0, j + 1) = set;
-+ }
-+
-+ rtx a = copy_reg (a7, -1);
-+ a->frame_related = 1;
-+ rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode,
regs_total_size));
-+ rtx set = gen_rtx_SET(a, plus);
-+ XVECEXP(parallel, 0, 0) = set;
-+ SET_INSN_DELETED(ii.get_insn ());
-+ ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
-+ }
-+ }
-+
-+ ii.unset (FRAME_POINTER_REGNUM);
-+ }
-+
-+ update_insn2index ();
-+ ++changed;
-+ }
-+ }
-+
-+ return changed;
-+}
-+
-+/* Update the insn_infos to 'know' the value for each register.
-+ *
-+ * assignments to registers are optimized by knowing the value. If the same value is
assigned, omit that insn.
-+ *
-+ * I'm tracking
-+ *
-+ * rtx - the value
-+ *
-+ * mask - the referenced registers in the value, 0 means that rtx is const, with
baserel a4 is not tracked
-+ *
-+ * if there is a value for the referenced register(s), the value is extended
-+ *
-+ * e.g.
-+ *
-+ * ; line 2
-+ * move.l 12(a7),a0
-+ *
-+ * -> rtx = mem(plus(a7, 12)); 0x8000
-+ *
-+ * ; line 10
-+ * move.l 4(a0),d0
-+ *
-+ * -> rtx = mem(plus(mem(plus(a7, 12)), 4)); 0x8000; extended with value from a0,
thus a7 is used only
-+ *
-+ * ;15
-+ * lea _label,a1
-+ *
-+ * -> rtx = symbol_ref(_label) ; 0x0000 == const
-+ *
-+ * on jumps the current state is duplicated and merged at the given label
-+ *
-+ * on merge only identical info is kept, rest is discarded
-+ *
-+ * for each insn for all defined regs the value and mask is discarded before a new
value is set.
-+ *
-+ * for each insn which is writing to memory, all non const values are discarded.
-+ *
-+ *
-+ * after the track info is complete, each insn setting a register is evaluated against
the track info.
-+ *
-+ * now redundant loads are found and eliminated
-+ *
-+ */
-+
-+static unsigned
-+track_regs ()
-+{
-+// reset visited flags
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+ }
-+
-+ update_label2jump ();
-+
-+// add entry point
-+ std::multimap<unsigned, track_var *> todo;
-+ todo.insert (std::make_pair (0, new track_var ()));
-+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = todo.begin ()->first;
-+ track_var * const track = todo.begin ()->second;
-+ todo.erase (todo.begin ());
-+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ // already visited?
-+ if (index != startpos && ii.is_visited () && ii.get_track_var
()->no_merge_needed (track))
-+ break;
-+
-+ // only keep common values at labels
-+ if (ii.is_label ())
-+ {
-+ if (ii.is_visited ())
-+ {
-+ ii.get_track_var ()->merge (track, index);
-+ }
-+ else
-+ {
-+ ii.get_track_var ()->assign (track);
-+ ii.mark_visited ();
-+ }
-+ continue;
-+ }
-+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.get_track_var ()->assign (track);
-+
-+ if (ii.is_compare ())
-+ continue;
-+
-+ unsigned def = ii.get_def () & 0xffffff;
-+ if (def)
-+ {
-+ // more than one register set? or mask from clobber?
-+ if (((def - 1) & def) || !ii.get_dst_reg ())
-+ track->clear_for_mask (def, index);
-+ }
-+ // do not clear if self assigned
-+ int dregno = ii.get_dst_regno ();
-+ if (dregno != ii.get_src_regno ())
-+ track->clear (ii.get_mode (), dregno, index);
-+
-+ if (ii.is_call ())
-+ {
-+ track->clear_aftercall (index);
-+ continue;
-+ }
-+
-+ rtx set = single_set (ii.get_insn ());
-+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ if (ANY_RETURN_P(ii.get_insn ()))
-+ break;
-+
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end ()
&& i->first == k->first; ++i)
-+ todo.insert (std::make_pair (i->second, new track_var (track)));
-+
-+ if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
-+ continue;
-+
-+ // unconditional jump
-+ break;
-+ }
-+
-+ if (!set || !ii.get_def ())
-+ continue;
-+
-+ if (dregno < 0)
-+ {
-+ track->invalidate_mem (SET_DEST(set));
-+ continue;
-+ }
-+
-+ // operation, autoinf or more than one register used: can't cache
-+ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) &
ii.get_myuse ()))
-+ continue;
-+
-+ rtx src = SET_SRC(set);
-+ if (ii.is_src_mem () && src->volatil)
-+ continue;
-+
-+ track->set (ii.get_mode (), dregno, src, index);
-+ }
-+ delete track;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Some optimizations (e.g. propagate_moves) might result into an unused assignment
behind the loop.
-+ * delete those insns.
-+ */
-+static unsigned
-+opt_elim_dead_assign (int blocked_regno)
-+{
-+ track_regs ();
-+
-+ unsigned change_count = 0;
-+ for (int index = infos.size () - 1; index >= 0; --index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () || !ii.get_dst_reg () || ii.is_compare ())
-+ continue;
-+
-+ rtx_insn * insn = ii.get_insn ();
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 &&
ii.get_dst_regno () != blocked_regno
-+ && is_reg_dead (ii.get_dst_regno (), index))
-+ {
-+ log ("(e) %d: eliminate dead assign to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ // check for redundant load
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno
() != blocked_regno
-+ && (!ii.is_myuse (ii.get_dst_regno ()) || ii.get_dst_regno () ==
ii.get_src_regno ()))
-+ {
-+ track_var * track = ii.get_track_var ();
-+
-+ rtx src = SET_SRC(set);
-+ if (track->equals (ii.get_dst_regno (), src))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ if (ii.get_src_reg () && track->equals (ii.get_src_regno (),
SET_DEST(set)))
-+ {
-+ log ("(e) %d: eliminate redundant reverse load to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ // is there a register holding that value?
-+ if (!ii.get_src_reg ())
-+ {
-+ int aliasRegno = track->find_alias (src);
-+ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno ())
-+ {
-+ log ("(e) %d: replace load with %s\n", index, reg_names[aliasRegno]);
-+ validate_change (ii.get_insn (), &SET_SRC(set), gen_rtx_REG (ii.get_mode (),
aliasRegno), 0);
-+ ++change_count;
-+ }
-+ }
-+ }
-+ }
-+ return change_count;
-+}
-+
-+/*
-+ * Convert a series of move into absolute address into register based moves.
-+ */
-+static unsigned
-+opt_absolute (void)
-+{
-+ unsigned change_count = 0;
-+
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+
-+ if (ii.is_compare ())
-+ continue;
-+
-+ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ())
-+ continue;
-+
-+ bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol
()) && !ii.has_dst_memreg ();
-+ bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol
()) && !ii.has_src_memreg ();
-+
-+ if (!is_dst && !is_src)
-+ continue;
-+
-+ if (ii.get_mode () == VOIDmode)
-+ continue;
-+
-+ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 &
usable_regs;
-+ if (!freemask)
-+ continue;
-+
-+ rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
-+
-+ std::vector<unsigned> found;
-+ found.push_back (i);
-+ int base = ii.get_dst_mem_addr ();
-+ int max = base;
-+ unsigned j = i + 1;
-+ for (; j < infos.size (); ++j)
-+ {
-+ insn_info & jj = infos[j];
-+ /* TODO: continue also at jump target */
-+ if (jj.is_jump ())
-+ continue;
-+ /* TODO: check if label is visited only from jump targets from herein. then the label
is ok. */
-+ if (jj.is_label ())
-+ break;
-+
-+ unsigned tempmask = freemask & ~(jj.get_use () | jj.get_def ());
-+ if (!tempmask)
-+ break;
-+ freemask = tempmask;
-+
-+ if (jj.get_mode () == VOIDmode || jj.is_compare ())
-+ continue;
-+
-+ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ())
-+ continue;
-+
-+ bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ())
&& !jj.has_dst_memreg ()
-+ && jj.get_dst_symbol () == with_symbol;
-+ bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ())
&& !jj.has_src_memreg ()
-+ && jj.get_src_symbol () == with_symbol;
-+
-+ /* exclude operations on that symbol. */
-+
-+ if (j_dst)
-+ {
-+ int addr = jj.get_dst_mem_addr ();
-+ if (addr < base)
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ if (j_src)
-+ {
-+ int addr = jj.get_src_mem_addr ();
-+ if (addr < base)
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ }
-+
-+ if (freemask && found.size () > 2)
-+ {
-+ unsigned regno = bit2regno (freemask);
-+ /* check again. */
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
-+ {
-+ insn_info & kk = infos[*k];
-+ bool k_dst = kk.is_dst_mem () && (kk.has_dst_addr () || kk.get_dst_symbol
()) && !kk.has_dst_memreg ()
-+ && kk.get_dst_symbol () == with_symbol;
-+ bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol
()) && !kk.has_src_memreg ()
-+ && kk.get_src_symbol () == with_symbol;
-+ if (k_dst && kk.get_dst_mem_addr () - base > 0x7ffc)
-+ k = found.erase (k);
-+ else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
-+ k = found.erase (k);
-+ else if (insn_invalid_p (make_insn_raw (kk.make_absolute2base (regno, base,
with_symbol, false)), 0))
-+ k = found.erase (k);
-+ else
-+ ++k;
-+ }
-+ }
-+ if (freemask && found.size () > 2)
-+ {
-+ unsigned regno = bit2regno (freemask);
-+ if (with_symbol)
-+ log ("(b) modifying %d symbol addresses for %s using %s\n", found.size
(),
-+ with_symbol->u.block_sym.fld[0].rt_str, reg_names[regno]);
-+ else
-+ log ("(b) modifying %d absolute addresses using %s\n", found.size (),
reg_names[regno]);
-+
-+ unsigned current_use = ii.get_use ();
-+
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();
++k)
-+ {
-+ insn_info & kk = infos[*k];
-+ kk.absolute2base (regno, base, with_symbol);
-+ insn_invalid_p (kk.get_insn (), 0);
-+ }
-+
-+ // load base into reg
-+ rtx lea;
-+
-+ if (with_symbol)
-+ {
-+ if (base)
-+ lea = gen_rtx_SET(
-+ gen_raw_REG (SImode, regno),
-+ gen_rtx_CONST (SImode, gen_rtx_PLUS (SImode, with_symbol, gen_rtx_CONST_INT
(SImode, base))));
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
-+ }
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
-+ insn_info nn (insn);
-+ nn.set_use (current_use);
-+ nn.scan ();
-+ nn.fledder (lea);
-+ nn.mark_def (regno);
-+ infos.insert (infos.begin () + i, nn);
-+
-+ /* mark until last hit is found. */
-+ for (unsigned k = i + 1; k < infos.size (); ++k)
-+ {
-+ infos[k].mark_use (regno);
-+ if (k == *found.rbegin ())
-+ break;
-+ }
-+ ++change_count;
-+ --i;
-+ }
-+ }
-+
-+ if (change_count)
-+ update_insn2index ();
-+
-+ return change_count;
-+}
-+
-+static int
-+try_auto_inc (unsigned index, insn_info & ii, rtx reg)
-+{
-+ int const regno = REGNO(reg);
-+ unsigned size = GET_MODE_SIZE(ii.get_mode ());
-+ if (size > 4)
-+ return 0;
-+
-+// log ("starting auto_inc search for %s at %d\n", reg_names[regno],
index);
-+
-+ // track all fixups to modify
-+ std::set<unsigned> fixups;
-+
-+ // all paths to check
-+ std::vector<unsigned> todo;
-+ todo.push_back (index + 1);
-+
-+ bool match_size = false;
-+ std::set<unsigned> visited;
-+ while (todo.size () > 0)
-+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-+
-+ if (pos == index)
-+ return 0;
-+
-+ if (visited.find (pos) != visited.end ())
-+ continue;
-+ visited.insert (pos);
-+
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & jj = infos[pos];
-+
-+ // check all jumps labels for register usage
-+ if (jj.is_label ())
-+ {
-+ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
-+ j != label2jump.end () && j->first == k->first; ++j)
-+ {
-+ insn_info * ll = insn2info.find (j->second)->second;
-+ if (ll->is_use (regno))
-+ return 0;
-+ }
-+ break;
-+ }
-+
-+ // break if no longer used
-+ if (!jj.is_use (regno))
-+ break;
-+
-+ if (jj.in_proepi ())
-+ return 0;
-+
-+ // add all labels
-+ if (jj.is_jump ())
-+ {
-+ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end ()
&& j->first == k->first; ++j)
-+ todo.push_back (j->second);
-+ continue;
-+ }
-+
-+ // not used directly
-+ if (!jj.is_myuse (regno))
-+ continue;
-+
-+ // can't fixup such kind of insn (yet)
-+ if (single_set (jj.get_insn ()) == 0)
-+ return 0;
-+
-+ // if reg is src reg, op must be add and addend must be large enough
-+ bool fix = false;
-+ if (jj.get_src_mem_regno () == regno)
-+ {
-+ if (jj.get_dst_regno () == regno)
-+ return 0;
-+
-+ if (jj.get_src_mem_addr () < size)
-+ return 0;
-+
-+ if (jj.get_src_mem_addr () == size)
-+ match_size = true;
-+
-+ fix = true;
-+ }
-+ if (jj.get_dst_mem_regno () == regno)
-+ {
-+ if (jj.get_src_regno () == regno)
-+ return 0;
-+
-+ if (jj.get_dst_mem_addr () < size)
-+ return 0;
-+
-+ if (jj.get_dst_mem_addr () == size)
-+ match_size = true;
-+
-+ fix = true;
-+ }
-+
-+ if (!fix)
-+ return 0;
-+
-+ fixups.insert (pos);
-+
-+ // done if this is an add
-+ if (ii.is_def (regno))
-+ break;
-+ }
-+ }
-+
-+ if (!match_size || !fixups.size ())
-+ return 0;
-+
-+ if (!ii.make_post_inc (regno))
-+ return 0;
-+
-+ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index,
fixups.size ());
-+
-+ // fix all offsets / adds
-+ for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-+ {
-+// log ("(i) fixup at %d\n", *k);
-+ insn_info & kk = infos[*k];
-+ kk.auto_inc_fixup (regno, size);
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+),
(ax+), (ax+), ...)
-+ *
-+ * 1. search a mem(reg) without offset and either src or dst is using that reg
-+ * 2. follow paths until reg is dead
-+ * 3. if there is another mem(reg) with offset check that
-+ * a) offset fits last mode size
-+ * b) all remaining insn using that reg can be updated by
-+ * i) decrement the offset
-+ * ii) decrement the add value
-+ */
-+static unsigned
-+opt_autoinc ()
-+{
-+ unsigned change_count = 0;
-+
-+ update_label2jump ();
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ if (ii.in_proepi ())
-+ continue;
-+
-+ if (!INSN_P(ii.get_insn ()))
-+ continue;
-+
-+// // more than one reg used
-+// if (ii.get_myuse () & (ii.get_myuse () - 1))
-+// continue;
-+
-+// // don't if fp regs are touched
-+// if ((ii.get_myuse () & 0xff0000))
-+// continue;
-+
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 &&
!ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () &&
ii.get_src_mem_regno () != ii.get_dst_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-+
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 &&
!ii.get_dst_intval () && !ii.get_dst_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () &&
ii.get_src_regno () != ii.get_dst_mem_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_dst_mem_reg ());
-+
-+ }
-+
-+ return change_count;
-+}
-+
-+namespace
-+{
-+
-+ const pass_data pass_data_bbb_optimizations =
-+ { RTL_PASS, /* type */
-+ "bebbo's-optimizers", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_optimizations : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_optimizations (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_optimizations, ctxt), pp (0)
-+ {
-+ }
-+
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ if (!string_bbb_opts)
-+ string_bbb_opts = "+";
-+
-+ return TARGET_AMIGA && optimize > 0 && string_bbb_opts
&& !strchr (string_bbb_opts, '-');
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_optimizations ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
-+ bbb->pp = pp + 1;
-+ return bbb;
-+ }
-+
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_optimizations (void);
-+ };
-+// class pass_bbb_optimizations
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_optimizations::execute_bbb_optimizations (void)
-+ {
-+ dump_reg_track = strchr (string_bbb_opts, 'R') != 0;
-+ be_very_verbose = strchr (string_bbb_opts, 'V') != 0;
-+ be_verbose = strchr (string_bbb_opts, 'v') != 0;
-+ if (be_verbose && be_very_verbose)
-+ ++be_very_verbose;
-+ if (be_very_verbose)
-+ be_verbose = true;
-+
-+ bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr
(string_bbb_opts, '+');
-+ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts,
'+');
-+ bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr
(string_bbb_opts, '+');
-+ bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr
(string_bbb_opts, '+');
-+ bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr
(string_bbb_opts, '+');
-+ bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts,
'+');
-+ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr
(string_bbb_opts, '+');
-+ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr
(string_bbb_opts, '+');
-+ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr
(string_bbb_opts, '+');
-+ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr
(string_bbb_opts, '+');
-+
-+ if (be_very_verbose)
-+ log ("ENTER\n");
-+
-+ unsigned r = update_insns ();
-+ if (!r)
-+ {
-+ for (;;)
-+ {
-+ int done = 1;
-+ if (do_opt_strcpy && opt_strcpy ())
-+ done = 0, update_insns ();
-+
-+ if (do_commute_add_move && opt_commute_add_move ())
-+ done = 0, update_insns ();
-+
-+ if (do_propagate_moves && opt_propagate_moves ())
-+ done = 0, update_insns ();
-+
-+ if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
-+ done = 0, update_insns ();
-+
-+ if (do_merge_add && opt_merge_add ())
-+ done = 0;
-+
-+ if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
-+ done = 0, update_insns ();
-+
-+ if (do_absolute && opt_absolute ())
-+ done = 0, update_insns ();
-+
-+ if (do_autoinc && opt_autoinc ())
-+ done = 0, update_insns ();
-+
-+ if (do_bb_reg_rename)
-+ {
-+ while (opt_reg_rename ())
-+ {
-+ update_insns ();
-+ done = 0;
-+ }
-+ }
-+
-+ if (done)
-+ break;
-+ }
-+
-+ if (do_shrink_stack_frame)
-+ {
-+ if (opt_shrink_stack_frame ())
-+ update_insns ();
-+ }
-+
-+ /* elim stack pointer stuff last. */
-+ if (do_elim_dead_assign)
-+ opt_elim_dead_assign (FIRST_PSEUDO_REGISTER);
-+ }
-+ if (r && be_verbose)
-+ log ("no bbb optimization code %d\n", r);
-+
-+ if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-+ dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
-+
-+ if (dump_reg_track)
-+ {
-+ update_insns ();
-+ track_regs ();
-+ }
-+
-+ return r;
-+ }
-+
-+} // anon namespace
-+
-+rtl_opt_pass *
-+make_pass_bbb_optimizations (gcc::context * ctxt)
-+{
-+ return new pass_bbb_optimizations (ctxt);
-+}
-+
-+namespace
-+{
-+
-+ const pass_data pass_data_bbb_baserel =
-+ { RTL_PASS, /* type */
-+ "bebbo's-baserel fixer", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_baserel : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_baserel (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_baserel, ctxt), pp (0)
-+ {
-+ }
-+
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ return TARGET_AMIGA && flag_pic >= 3;
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_baserel ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ pass_bbb_baserel * bbb = new pass_bbb_baserel (m_ctxt);
-+ return bbb;
-+ }
-+
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_baserel (void);
-+ };
-+// class pass_bbb_optimizations
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_baserel::execute_bbb_baserel (void)
-+ {
-+ rtx_insn *insn, *next;
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx * src = &SET_SRC(set);
-+ if (MEM_P(*src))
-+ src = &XEXP(*src, 0);
-+
-+ bool ispicref = false;
-+ // fix add PLUS/MINUS into the unspec offset
-+ if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-+ ispicref = amiga_is_const_pic_ref (XEXP(*src, 0));
-+ else
-+ ispicref = amiga_is_const_pic_ref (*src);
-+
-+ if (ispicref)
-+ {
-+ rtx dest = SET_DEST(set);
-+ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC)
-+ {
-+ // split the insn
-+ rtx reg = gen_reg_rtx (Pmode);
-+
-+ rtx pat0 = gen_rtx_SET(reg, *src);
-+ //rtx_insn * n0 =
-+ emit_insn_before (pat0, insn);
-+
-+ rtx pat1 = gen_rtx_SET(dest, reg);
-+ //rtx_insn * n1 =
-+ emit_insn_before (pat1, insn);
-+
-+ SET_INSN_DELETED(insn);
-+ }
-+ }
-+ }
-+ }
-+
-+ return 0;
-+ }
-+
-+} // anon namespace
-+
-+rtl_opt_pass *
-+make_pass_bbb_baserel (gcc::context * ctxt)
-+{
-+ return new pass_bbb_baserel (ctxt);
-+}
-diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-index e8bafedd7357..642829b828c7 100644
---- gcc/c/c-decl.c
-+++ gcc/c/c-decl.c
-@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
- #include "c-family/c-ada-spec.h"
- #include "cilk.h"
- #include "builtins.h"
-+#include "output.h"
-+#include "tm_p.h"
-
- /* In grokdeclarator, distinguish syntactic contexts of declarators. */
- enum decl_context
-@@ -4439,7 +4441,32 @@ c_decl_attributes (tree *node, tree attributes, int flags)
- attributes = tree_cons (get_identifier ("omp declare target"),
- NULL_TREE, attributes);
- }
-- return decl_attributes (node, attributes, flags);
-+
-+ tree returned_attrs = decl_attributes (node, attributes, flags);
-+
-+#ifdef TARGET_AMIGA
-+ /* add an attribute to the function decl's type if there are asm register
parameters. */
-+ if (TREE_CODE (*node) == FUNCTION_DECL)
-+ {
-+ char const * synthetic = "";
-+ for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params =
TREE_CHAIN(params))
-+ {
-+ tree asmattr = lookup_attribute("asm",
TYPE_ATTRIBUTES(TREE_VALUE(params)));
-+ if (asmattr)
-+ synthetic = concat(synthetic,
reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], NULL);
-+ }
-+ if (strlen(synthetic) > 0)
-+ {
-+ tree asmid = get_identifier("asmregs");
-+ tree syntheticid = get_identifier(synthetic);
-+ tree newattr = tree_cons(asmid, syntheticid, NULL_TREE);
-+
-+ TYPE_ATTRIBUTES(TREE_TYPE(*node)) = chainon(newattr,
TYPE_ATTRIBUTES(TREE_TYPE(*node)));
-+ }
-+ }
-+#endif
-+
-+ return returned_attrs;
- }
-
-
-@@ -5024,6 +5051,29 @@ grokparm (const struct c_parm *parm, tree *expr)
- return decl;
- }
-
-+#ifdef TARGET_AMIGA
-+
-+/* Create a new variant of TYPE, equivalent but distinct.
-+ This is so the caller can modify it. */
-+
-+static tree
-+build_type_copy (tree type)
-+ {
-+ tree t, m = TYPE_MAIN_VARIANT (type);
-+
-+ t = copy_node (type);
-+
-+ TYPE_POINTER_TO (t) = 0;
-+ TYPE_REFERENCE_TO (t) = 0;
-+
-+ /* Add this type to the chain of variants of TYPE. */
-+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
-+ TYPE_NEXT_VARIANT (m) = t;
-+
-+ return t;
-+ }
-+#endif
-+
- /* Given a parsed parameter declaration, decode it into a PARM_DECL
- and push that on the current scope. EXPR is a pointer to an
- expression that needs to be evaluated for the side effects of array
-@@ -5041,6 +5091,59 @@ push_parm_decl (const struct c_parm *parm, tree *expr)
-
- decl = pushdecl (decl);
-
-+#ifdef TARGET_AMIGAOS
-+ if (parm->asmspec)
-+ {
-+ tree atype = TREE_TYPE(decl);
-+ const char *asmspec = TREE_STRING_POINTER(parm->asmspec);
-+ if (*asmspec == '%')
-+ ++asmspec;
-+ int reg_number = decode_reg_name (asmspec);
-+
-+ /* First detect errors in declaring global registers. */
-+ if (reg_number == -1)
-+ error ("%Jregister name not specified for %qD", decl, decl);
-+ else if (reg_number < 0)
-+ error ("%Jinvalid register name for %qD", decl, decl);
-+ else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
-+ error ("%Jdata type of %qD isn%'t suitable for a register", decl, decl);
-+ else if (!HARD_REGNO_MODE_OK(reg_number, TYPE_MODE (TREE_TYPE (decl))))
-+ error ("%Jregister specified for %qD isn%'t suitable for data type",
-+ decl, decl);
-+ /* Now handle properly declared static register variables. */
-+ else
-+ {
-+ /* Build tree for __attribute__ ((asm(regnum))). */
-+ FIXED_VALUE_TYPE fv =
-+ { reg_number, 0, BImode };
-+ tree ttasm = get_identifier("asm");
-+ tree t, attrs = tree_cons(ttasm, build_fixed (ttasm, fv), NULL_TREE);
-+ /* First check whether such a type already exists - if yes, use
-+ that one. This is very important, since otherwise
-+ common_type() would think that it sees two different
-+ types and would try to merge them - this could result in
-+ warning messages. */
-+ for (t = TYPE_MAIN_VARIANT(atype); t; t = TYPE_NEXT_VARIANT(t))
-+ if (comptypes (t, atype) == 1
-+ && attribute_list_equal (TYPE_ATTRIBUTES(t), attrs))
-+ break;
-+ if (t)
-+ atype = t;
-+ else
-+ {
-+ /* Create a new variant, with differing attributes.
-+ (Hack! Type with differing attributes should no longer be
-+ a variant of its main type. See comment above for
-+ explanation why this was necessary). */
-+ atype = build_type_copy (atype);
-+ TYPE_ATTRIBUTES(atype) = chainon (attrs, TYPE_ATTRIBUTES(atype));
-+ }
-+ TREE_TYPE(decl) = atype;
-+// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME
(decl)), asmspec, decl, atype);
-+ }
-+ }
-+#endif
-+
- finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
- }
-
-diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
-index fc20bad8d992..91cfc2c5e193 100644
---- gcc/c/c-parser.c
-+++ gcc/c/c-parser.c
-@@ -3837,10 +3837,26 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
- c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- return NULL;
- }
-+ /**
-+ * SBF: Add support for __asm("xy") register spec.
-+ */
-+#ifdef TARGET_AMIGAOS
-+ tree asmspec = NULL_TREE;
-+ if (c_parser_next_token_is_keyword (parser, RID_ASM))
-+ {
-+ asmspec = c_parser_simple_asm_expr (parser);
-+// printf("asmspec: %s\n", TREE_STRING_POINTER(asmspec));
-+ }
-+#endif
- if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
- postfix_attrs = c_parser_attributes (parser);
-- return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
-+
-+ struct c_parm * cparm = build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
- declarator);
-+#ifdef TARGET_AMIGAOS
-+ cparm->asmspec = asmspec;
-+#endif
-+ return cparm;
- }
-
- /* Parse a string literal in an asm expression. It should not be
-@@ -3892,6 +3908,7 @@ c_parser_asm_string_literal (c_parser *parser)
- static tree
- c_parser_simple_asm_expr (c_parser *parser)
- {
-+ extern int in_assembler_directive;
- tree str;
- gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
- /* ??? Follow the C++ parser rather than using the
-@@ -3903,7 +3920,13 @@ c_parser_simple_asm_expr (c_parser *parser)
- parser->lex_untranslated_string = false;
- return NULL_TREE;
- }
-+
-+ // SBF: set in_assembler_directive to enable multi-line strings. And yes, it's a
HACK.
-+ in_assembler_directive = 1;
- str = c_parser_asm_string_literal (parser);
-+ // SBF: in_assembler_directive disabled
-+ in_assembler_directive = 0;
-+
- parser->lex_untranslated_string = false;
- if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
- {
-diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
-index bb12a200f709..e3404fd8b0a6 100644
---- gcc/c/c-tree.h
-+++ gcc/c/c-tree.h
-@@ -453,6 +453,10 @@ struct c_parm {
- tree attrs;
- /* The declarator. */
- struct c_declarator *declarator;
-+#ifdef TARGET_AMIGAOS
-+ /* The optional asm spec to specify the register. */
-+ tree asmspec;
-+#endif
- };
-
- /* Used when parsing an enum. Initialized by start_enum. */
-diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
-index 6e92d4cdde22..378b1fc595bb 100644
---- gcc/cfgcleanup.c
-+++ gcc/cfgcleanup.c
-@@ -2001,6 +2001,15 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- {
- rtx_insn *insn;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * we need replicated labels, if the labels are too far away,
-+ * since on 68000 there are only 8 bits for the offset.
-+ */
-+ if (!TARGET_68020 && !TARGET_68040)
-+ return false;
-+#endif
-+
- /* Replace references to LABEL1 with LABEL2. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
-@@ -2016,8 +2025,9 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- /* Avoid splitting if possible. We must always split when SRC2 has
- EH predecessor edges, or we may end up with basic blocks with both
- normal and EH predecessor edges. */
-- if (newpos2 == BB_HEAD (src2)
-+ if ((newpos2 == BB_HEAD (src2)
- && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
-+ )
- redirect_to = src2;
- else
- {
-diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
-index b612293b1a7a..4215ae90c63d 100644
---- gcc/cfgexpand.c
-+++ gcc/cfgexpand.c
-@@ -2732,6 +2732,10 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET
*clobbered_regs)
- {
- /* Conflicts between asm-declared register variables and the clobber
- list are not allowed. */
-+ /*
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
-
- if (overlap)
-@@ -2744,7 +2748,7 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET
*clobbered_regs)
- DECL_REGISTER (overlap) = 0;
- return true;
- }
--
-+#endif
- return false;
- }
-
-@@ -3255,11 +3259,15 @@ expand_asm_stmt (gasm *stmt)
- if (reg_overlap_mentioned_p (clobbered_reg, output_rvec[k]))
- internal_error ("asm clobber conflict with output operand");
-
-+/**
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- for (unsigned k = 0; k < ninputs - ninout; ++k)
- if (reg_overlap_mentioned_p (clobbered_reg, input_rvec[k]))
- internal_error ("asm clobber conflict with input operand");
-+#endif
- }
--
- XVECEXP (body, 0, i++) = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
- }
-
-diff --git a/gcc/collect2.c b/gcc/collect2.c
-index bffac802b8fe..f52a66ef1b58 100644
---- gcc/collect2.c
-+++ gcc/collect2.c
-@@ -1392,6 +1392,11 @@ main (int argc, char **argv)
- add_to_list (&libs, s);
- }
- #endif
-+ /* begin-GG-local: dynamic libraries */
-+ #ifdef COLLECT2_LIBNAME_HOOK
-+ COLLECT2_LIBNAME_HOOK(arg);
-+ #endif
-+ /* end-GG-local */
- break;
-
- #ifdef COLLECT_EXPORT_LIST
-@@ -1492,6 +1497,11 @@ main (int argc, char **argv)
- add_to_list (&libs, arg);
- }
- #endif
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_LIBNAME_HOOK
-+ COLLECT2_LIBNAME_HOOK(arg);
-+#endif
-+ /* end-GG-local */
- }
- }
-
-@@ -1608,6 +1618,11 @@ main (int argc, char **argv)
-
- fprintf (stderr, "\n");
- }
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_PRELINK_HOOK
-+ COLLECT2_PRELINK_HOOK(ld1_argv, &strip_flag);
-+#endif
-+ /* end-GG-local */
-
- /* Load the program, searching all libraries and attempting to provide
- undefined symbols from repository information.
-@@ -1648,6 +1663,8 @@ main (int argc, char **argv)
- }
- }
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifndef COLLECT2_POSTLINK_HOOK
- /* Unless we have done it all already, examine the namelist and search for
- static constructors and destructors to call. Write the constructor and
- destructor tables to a .s file and reload. */
-@@ -1674,6 +1691,10 @@ main (int argc, char **argv)
- frame_tables.number),
- frame_tables.number);
- }
-+#else /* COLLECT2_POSTLINK_HOOK */
-+ COLLECT2_POSTLINK_HOOK(output_file);
-+#endif
-+/* end-GG-local */
-
- /* If the scan exposed nothing of special interest, there's no need to
- generate the glue code and relink so return now. */
-@@ -1716,6 +1737,11 @@ main (int argc, char **argv)
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_EXTRA_CLEANUP
-+ COLLECT2_EXTRA_CLEANUP();
-+#endif
-+ /* end-GG-local */
- return 0;
- }
-
-@@ -1821,6 +1847,11 @@ main (int argc, char **argv)
- maybe_unlink (export_file);
- #endif
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_EXTRA_CLEANUP
-+ COLLECT2_EXTRA_CLEANUP();
-+#endif
-+ /* end-GG-local */
- return 0;
- }
-
-diff --git a/gcc/config.gcc b/gcc/config.gcc
-index bf3f32da08ac..7aa190620911 100644
---- gcc/config.gcc
-+++ gcc/config.gcc
-@@ -1940,6 +1940,27 @@ m68k-*-elf* | fido-*-elf*)
- ;;
- esac
- ;;
-+m68k*-*-amigaosvasm*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_AMIGAOS_VASM
TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ ;;
-+m68k*-*-amigaos*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ CFLAGS="-Os"
-+ ;;
- m68k*-*-netbsdelf*)
- default_m68k_cpu=68020
- default_cf_cpu=5475
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-new file mode 100644
-index 000000000000..e5cd6e950b52
---- /dev/null
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -0,0 +1,55 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#undef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree);
-+
-+/* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+#undef INIT_CUMULATIVE_ARGS
-+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
-+ (amigaos_init_cumulative_args(&(CUM), (FNTYPE), (INDIRECT)))
-+
-+#ifdef RTX_CODE
-+extern int read_only_operand (rtx);
-+extern void amigaos_select_section (tree, int, unsigned HOST_WIDE_INT);
-+extern void amigaos_encode_section_info (tree, rtx, int);
-+extern void amigaos_alternate_pic_setup (FILE *);
-+extern void amigaos_prologue_begin_hook (FILE *, int);
-+extern void amigaos_alternate_frame_setup_f (FILE *, int);
-+extern void amigaos_alternate_frame_setup (FILE *, int);
-+extern struct rtx_def* gen_stack_cleanup_call (rtx, rtx);
-+extern void amigaos_alternate_allocate_stack (rtx *);
-+#ifdef TREE_CODE
-+//extern void amigaos_function_arg_advance (CUMULATIVE_ARGS *);
-+extern struct rtx_def *amigaos_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
tree);
-+#endif
-+#endif
-+#ifdef TREE_CODE
-+extern tree amigaos_handle_decl_attribute (tree *, tree, tree, int, bool *);
-+extern tree amigaos_handle_type_attribute (tree *, tree, tree, int, bool *);
-+#endif
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-new file mode 100644
-index 000000000000..28d20a980978
---- /dev/null
-+++ gcc/config/m68k/amigaos.c
-@@ -0,0 +1,931 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+
-+ GCC is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+//work without flag_writable_strings which is not in GCC4
-+#define REGPARMS_68K 1
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "output.h"
-+#include "tree.h"
-+#include "attribs.h"
-+#include "flags.h"
-+#include "expr.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "target.h"
-+#include "diagnostic-core.h"
-+#include "langhooks.h"
-+#include "function.h"
-+#include "config/m68k/amigaos.h"
-+
-+//#define MYDEBUG 1
-+#ifdef MYDEBUG
-+#define DPRINTF(x) printf x; fflush(stdout);
-+#else
-+#define DPRINTF(x)
-+#endif
-+
-+//int amiga_declare_object;
-+
-+#if 0
-+
-+//----- from 68k.c start
-+
-+/* Stack checking and automatic extension support. */
-+
-+void
-+amigaos_prologue_begin_hook (FILE *stream, int fsize)
-+ {
-+ if (TARGET_STACKCHECK)
-+ {
-+ if (fsize < 256)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tjra %U__stkovf\n"
-+ "\t0:\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")));
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__stkchk_d0\n",
-+ fsize);
-+ }
-+ }
-+
-+
-+//static rtx
-+//gen_stack_management_call (rtx stack_pointer, rtx arg, const char *func)
-+//{
-+// rtx call_insn, call, seq, name;
-+// start_sequence ();
-+//
-+// /* Move arg to d0. */
-+// emit_move_insn (gen_rtx_REG (SImode, 0), arg);
-+//
-+// /* Generate the function reference. */
-+// name = gen_rtx_SYMBOL_REF (Pmode, func);
-+// SYMBOL_REF_FLAG (name) = 1;
-+// /* If optimizing, put it in a psedo so that several loads can be merged
-+// into one. */
-+// if (optimize && ! flag_no_function_cse)
-+// name = copy_to_reg (name);
-+//
-+// /* Generate the function call. */
-+// call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (FUNCTION_MODE, name),
-+// const0_rtx);
-+// /* If we are doing stack extension, notify about the sp change. */
-+// if (stack_pointer)
-+// call = gen_rtx_SET (VOIDmode, stack_pointer, call);
-+//
-+// /* Generate the call instruction. */
-+// call_insn = emit_call_insn (call);
-+// /* Stack extension does not change memory in an unpredictable way. */
-+// RTL_CONST_OR_PURE_CALL_P (call_insn) = 1;
-+// /* We pass an argument in d0. */
-+// CALL_INSN_FUNCTION_USAGE (call_insn) = gen_rtx_EXPR_LIST (VOIDmode,
-+// gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 0)), 0);
-+//
-+// seq = get_insns ();
-+// end_sequence ();
-+// return seq;
-+//}
-+//
-+//rtx
-+//gen_stack_cleanup_call (rtx stack_pointer, rtx sa)
-+//{
-+// return gen_stack_management_call (stack_pointer, sa, "__move_d0_sp");
-+//}
-+//
-+//void
-+//amigaos_alternate_allocate_stack (rtx *operands)
-+//{
-+// if (TARGET_STACKEXTEND)
-+// emit_insn (gen_stack_management_call (stack_pointer_rtx, operands[1],
-+// "__sub_d0_sp"));
-+// else
-+// {
-+// if (TARGET_STACKCHECK)
-+// emit_insn (gen_stack_management_call (0, operands[1], "__stkchk_d0"));
-+// anti_adjust_stack (operands[1]);
-+// }
-+// emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
-+//}
-+#endif
-+
-+/*
-+ * begin-GG-local: explicit register specification for parameters.
-+ *
-+ * Reworked and ported to gcc-6.2.0 by Stefan "Bebbo" Franke.
-+ */
-+
-+/**
-+ * Define this here and add it to tm_p -> all know the custom type and allocate/use
the correct size.
-+ */
-+struct amigaos_args
-+{
-+ int num_of_regs;
-+ long regs_already_used;
-+ int last_arg_reg;
-+ int last_arg_len;
-+ tree formal_type; /* New field: formal type of the current argument. */
-+};
-+
-+static struct amigaos_args mycum, othercum;
-+
-+/* Argument-passing support functions. */
-+
-+/* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+void
-+amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
-+{
-+ struct amigaos_args * cum = decl == current_function_decl ? &mycum :
&othercum;
-+ *cump = decl == current_function_decl;
-+ cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-+ DPRINTF(
-+ ("0amigaos_init_cumulative_args %s %p -> %d\r\n", decl ?
lang_hooks.decl_printable_name (decl, 2) : "?", cum, cum->num_of_regs));
-+
-+ /* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+ cum->last_arg_reg = -1;
-+ cum->regs_already_used = 0;
-+
-+ if (fntype)
-+ {
-+ tree attrs = TYPE_ATTRIBUTES(fntype);
-+ if (attrs)
-+ {
-+ if (lookup_attribute ("stkparm", attrs))
-+ cum->num_of_regs = 0;
-+ else
-+ {
-+ tree ratree = lookup_attribute ("regparm", attrs);
-+ cum->num_of_regs = amigaos_regparm != 0 ?
-+ amigaos_regparm :
-+ AMIGAOS_DEFAULT_REGPARM;
-+ if (ratree)
-+ {
-+ tree args = TREE_VALUE(ratree);
-+
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-+ cum->num_of_regs = no;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ else
-+ /* Libcall. */
-+ cum->num_of_regs = 0;
-+
-+ if (cum->num_of_regs)
-+ {
-+ /* If this is a vararg call, put all arguments on stack. */
-+ tree param, next_param;
-+ for (param = TYPE_ARG_TYPES(fntype); param; param = next_param)
-+ {
-+ next_param = TREE_CHAIN(param);
-+ if (!next_param && TREE_VALUE (param) != void_type_node)
-+ cum->num_of_regs = 0;
-+ }
-+ }
-+
-+#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (M68K_STRUCT_VALUE_REGNUM)
-+ /* If return value is a structure, and we pass the buffer address in a
-+ register, we can't use this register for our own purposes.
-+ FIXME: Something similar would be useful for static chain. */
-+ if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
-+ cum->regs_already_used |= (1 << M68K_STRUCT_VALUE_REGNUM);
-+#endif
-+
-+ if (fntype && DECL_STATIC_CHAIN(fntype))
-+ {
-+ rtx reg = amigaos_static_chain_rtx (decl, 0);
-+ if (reg)
-+ cum->regs_already_used |= (1 << REGNO(reg));
-+ }
-+
-+ if (fntype)
-+ cum->formal_type = TYPE_ARG_TYPES(fntype);
-+ else
-+ /* Call to compiler-support function. */
-+ cum->formal_type = 0;
-+ DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum,
cum->num_of_regs));
-+}
-+
-+int
-+amigaos_function_arg_reg (unsigned regno)
-+{
-+ return (mycum.regs_already_used & (1 << regno)) != 0;
-+}
-+
-+/* Update the data in CUM to advance over an argument. */
-+
-+void
-+amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree, bool)
-+{
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-+ /* Update the data in CUM to advance over an argument. */
-+
-+ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cum));
-+
-+ if (cum->last_arg_reg != -1)
-+ {
-+ int count;
-+ for (count = 0; count < cum->last_arg_len; count++)
-+ cum->regs_already_used |= (1 << (cum->last_arg_reg + count));
-+ cum->last_arg_reg = -1;
-+ }
-+
-+ if (cum->formal_type)
-+ cum->formal_type = TREE_CHAIN(cum->formal_type);
-+}
-+
-+/* Define where to put the arguments to a function.
-+ Value is zero to push the argument on the stack,
-+ or a hard register in which to store the argument.
-+
-+ MODE is the argument's machine mode.
-+ TYPE is the data type of the argument (as a tree).
-+ This is null for libcalls where that information may
-+ not be available.
-+ CUM is a variable of type CUMULATIVE_ARGS which gives info about
-+ the preceding args and about the function being called. */
-+
-+static struct rtx_def *
-+_m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree type)
-+{
-+ DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs :
0));
-+
-+ if (cum->num_of_regs)
-+ {
-+ int regbegin = -1, altregbegin = -1, len;
-+
-+ /* FIXME: The last condition below is a workaround for a bug. */
-+ if (TARGET_68881 && FLOAT_MODE_P(mode) &&
-+ GET_MODE_UNIT_SIZE (mode) <= 12 && (GET_MODE_CLASS (mode) !=
MODE_COMPLEX_FLOAT || mode == SCmode))
-+ {
-+ regbegin = 16; /* FPx */
-+ len = GET_MODE_NUNITS(mode);
-+ }
-+ /* FIXME: Two last conditions below are workarounds for bugs. */
-+ else if (INTEGRAL_MODE_P (mode) && mode != CQImode && mode !=
CHImode)
-+ {
-+ if (!type || POINTER_TYPE_P(type))
-+ regbegin = 8; /* Ax */
-+ else
-+ regbegin = 0; /* Dx */
-+ altregbegin = 8 - regbegin;
-+ len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
-+ }
-+
-+ if (regbegin != -1)
-+ {
-+ int reg;
-+ long mask;
-+
-+ look_for_reg: mask = 1 << regbegin;
-+ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1)
-+ if (!(cum->regs_already_used & mask))
-+ {
-+ int end;
-+ for (end = reg; end < cum->num_of_regs && end < reg + len; end++,
mask <<= 1)
-+ if (cum->regs_already_used & mask)
-+ break;
-+ if (end == reg + len)
-+ {
-+ cum->last_arg_reg = reg + regbegin;
-+ cum->last_arg_len = len;
-+ break;
-+ }
-+ }
-+
-+ if (reg == cum->num_of_regs && altregbegin != -1)
-+ {
-+ DPRINTF(("look for alt reg\n"));
-+ regbegin = altregbegin;
-+ altregbegin = -1;
-+ goto look_for_reg;
-+ }
-+ }
-+
-+ if (cum->last_arg_reg != -1)
-+ {
-+ DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
-+ return gen_rtx_REG (mode, cum->last_arg_reg);
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* A C expression that controls whether a function argument is passed
-+ in a register, and which register. */
-+
-+struct rtx_def *
-+amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type,
bool)
-+{
-+ DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
-+
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-+
-+ tree asmtree = type ? TYPE_ATTRIBUTES(cum->formal_type ?
TREE_VALUE(cum->formal_type) : type) : NULL_TREE;
-+ //tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
-+
-+ if (asmtree && 0 == strcmp ("asm",
IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ {
-+ int i;
-+ cum->last_arg_reg = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ cum->last_arg_len = HARD_REGNO_NREGS(cum->last_arg_reg, mode);
-+
-+ for (i = 0; i < cum->last_arg_len; i++)
-+ {
-+ if (cum->regs_already_used & (1 << (cum->last_arg_reg + i)))
-+ {
-+ error ("two parameters allocated for one register");
-+ break;
-+ }
-+ cum->regs_already_used |= (1 << (cum->last_arg_reg + i));
-+ }
-+ return gen_rtx_REG (mode, cum->last_arg_reg);
-+ }
-+ return _m68k_function_arg (cum, mode, type);
-+}
-+
-+void
-+amiga_emit_regparm_clobbers (void)
-+{
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ if (mycum.regs_already_used & (1 << i))
-+ {
-+ rtx reg = gen_raw_REG (Pmode, i);
-+ emit_insn (gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
-+ }
-+}
-+
-+/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
-+ one if they are compatible, and two if they are nearly compatible
-+ (which causes a warning to be generated). */
-+
-+int
-+amigaos_comp_type_attributes (const_tree type1, const_tree type2)
-+{
-+ DPRINTF(("amigaos_comp_type_attributes\n"));
-+ /* Functions or methods are incompatible if they specify mutually exclusive
-+ ways of passing arguments. */
-+ if (TREE_CODE(type1) == FUNCTION_TYPE || TREE_CODE(type1) == METHOD_TYPE)
-+ {
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree asm1 = lookup_attribute("asmregs", attrs1);
-+ tree stack1 = lookup_attribute("stkparm", attrs1);
-+ tree reg1 = lookup_attribute("regparm", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree asm2 = lookup_attribute("asmregs", attrs2);
-+ tree stack2 = lookup_attribute("stkparm", attrs2);
-+ tree reg2 = lookup_attribute("regparm", attrs2);
-+
-+ if (reg1)
-+ {
-+ if (stack2 || asm2)
-+ return 0;
-+
-+ int no1 = TREE_INT_CST_LOW(TREE_VALUE(reg1));
-+ int no2 = reg2 ? TREE_INT_CST_LOW(TREE_VALUE(reg2)) : amigaos_regparm;
-+ return no1 == no2;
-+ }
-+
-+ if (reg2)
-+ {
-+ if (stack1 || asm1)
-+ return 0;
-+
-+ int no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2));
-+ return amigaos_regparm == no2;
-+ }
-+
-+ if (stack1) {
-+ if (stack2)
-+ return 1;
-+ return amigaos_regparm == 0;
-+ }
-+
-+ if (stack2)
-+ return amigaos_regparm == 0;
-+
-+ if (asm1)
-+ {
-+ if (!asm2)
-+ return 0;
-+
-+ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)),
IDENTIFIER_POINTER(TREE_VALUE(asm2)));
-+ }
-+
-+ if (asm2)
-+ return 0;
-+
-+ }
-+ else
-+ {
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree chip1 = lookup_attribute("chip", attrs1);
-+ tree fast1 = lookup_attribute("fast", attrs1);
-+ tree far1 = lookup_attribute("far", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree chip2 = lookup_attribute("chip", attrs2);
-+ tree fast2 = lookup_attribute("fast", attrs2);
-+ tree far2 = lookup_attribute("far", attrs2);
-+
-+ if (chip1)
-+ return chip2 && !fast2 && !far2;
-+
-+ if (fast1)
-+ return !chip2 && fast2 && !far2;
-+
-+ if (far1)
-+ return !chip2 && !fast2 && far2;
-+
-+ return !chip2 && !fast2 && !far2;
-+ }
-+ return 1;
-+}
-+/* end-GG-local */
-+
-+/* Handle a regparm, stkparm, saveds attribute;
-+ arguments as in struct attribute_spec.handler. */
-+tree
-+amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags
ATTRIBUTE_UNUSED, bool *no_add_attrs)
-+{
-+ tree nnn = *node;
-+ do
-+ { // while (0);
-+ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-+ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE ||
TREE_CODE (nnn) == METHOD_TYPE)
-+ {
-+ /* 'regparm' accepts one optional argument - number of registers in
-+ single class that should be used to pass arguments. */
-+ if (is_attribute_p ("regparm", name))
-+ {
-+ DPRINTF(("regparm found\n"));
-+
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-+ {
-+ error ("`regparm' attribute: value %d not in [0 - %d]", no,
-+ AMIGAOS_MAX_REGPARM);
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ error ("invalid argument(s) to `regparm' attribute");
-+ break;
-+ }
-+ }
-+ }
-+ else if (is_attribute_p ("stkparm", name))
-+ {
-+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ }
-+ else if (is_attribute_p ("stackext", name))
-+ {
-+ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`stackext' and `interrupt' are mutually exclusive");
-+ break;
-+ }
-+ }
-+ else if (is_attribute_p ("saveds", name))
-+ {
-+ if (flag_pic < 3)
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute is only usable with
fbaserel", IDENTIFIER_POINTER(name));
-+ }
-+ else
-+ if (flag_resident)
-+ {
-+ error ("`saveds' can't be used with resident!\n");
-+ }
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to data",
IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ else
-+ {
-+ if (is_attribute_p ("chip", name) || is_attribute_p ("fast",
name) || is_attribute_p ("far", name))
-+ {
-+ // OK
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to
functions", IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ return NULL_TREE ;
-+ }
-+ while (0);
-+ // error case
-+ *no_add_attrs = true;
-+ return NULL_TREE ;
-+}
-+
-+#define AMIGA_CHIP_SECTION_NAME ".datachip"
-+#define AMIGA_FAST_SECTION_NAME ".datafast"
-+#define AMIGA_FAR_SECTION_NAME ".datafar"
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr)
-+{
-+ if (!*attr)
-+ return;
-+
-+ tree name = TREE_PURPOSE(*attr);
-+
-+ if (is_attribute_p("chip", name) || is_attribute_p("far", name) ||
is_attribute_p("fast", name))
-+ {
-+ if (!TREE_TYPE(decl) == VAR_DECL)
-+ {
-+ error ("`%s' attribute can only be specified for variables",
IDENTIFIER_POINTER(name));
-+ return;
-+ }
-+
-+ if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
-+ {
-+ error ("`%s' attribute cannot be specified for local variables",
IDENTIFIER_POINTER(name));
-+ return;
-+ }
-+
-+ char const * section_name;
-+ if (is_attribute_p("chip", name))
-+ section_name = AMIGA_CHIP_SECTION_NAME;
-+ else if (is_attribute_p("fast", name))
-+ section_name = AMIGA_FAST_SECTION_NAME;
-+ else if (is_attribute_p("far", name))
-+ section_name = AMIGA_FAR_SECTION_NAME;
-+
-+
-+ /* The decl may have already been given a section attribute from
-+ a previous declaration. Ensure they match. */
-+ if (DECL_SECTION_NAME (decl) == NULL)
-+ set_decl_section_name(decl, section_name);
-+ else if (strcmp (DECL_SECTION_NAME (decl), section_name) )
-+ {
-+ error_at (DECL_SOURCE_LOCATION(decl),
-+ "`%s' attribute conflicts with previous declaration",
IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ else
-+ {
-+// warning (OPT_Wattributes, "`%s' attribute unknown",
IDENTIFIER_POINTER(name));
-+ }
-+}
-+
-+extern bool
-+m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+
-+bool
-+amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool
speed)
-+{
-+// DPRINTF(("outer: %d, opno: %d", outer_code, opno));
-+ bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
-+// *total *= 4;
-+// fprintf(stderr, "costs: %d, mode=%d, outer=%d, opno=%d, speed=%d,
ok=%d\n", *total * 4, mode, outer_code, opno, speed, r);
-+// debug_rtx(x);
-+ return r;
-+}
-+
-+/* Output assembly to switch to section NAME with attribute FLAGS. */
-+#ifndef TARGET_AMIGAOS_VASM
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl )
-+{
-+ // only one code section - TODO: with amiga hunk this is no longer mandatory.
-+ if (0 == strncmp (".text", name, 5))
-+ name = ".text";
-+
-+ if (0 == strncmp(".data", name, 5) && (!DECL_INITIAL (decl) ||
initializer_zerop (DECL_INITIAL (decl))))
-+ fprintf (asm_out_file, "\t.bss%s\n", name + 5);
-+ else
-+ fprintf (asm_out_file, "\t%s\n", name);
-+}
-+#else
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
-+ {
-+ if (0 == strncmp(".text", name, 5))
-+ name = ".text";
-+
-+ if (0 == strncmp("section ", name, 8))
-+ {
-+// fprintf (asm_out_file, "\t.section\t%s\n", name);
-+ fprintf (asm_out_file, "\t%s\n", name);
-+ }
-+ else
-+ {
-+ fprintf (asm_out_file, "\tsection %s\n", name);
-+ }
-+ }
-+#endif
-+
-+/* Baserel support. */
-+
-+/**
-+ * Does x reference the pic_reg and is const or plus?
-+ */
-+static int
-+_amiga_is_const_pic_ref (const_rtx x)
-+{
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS)
-+ {
-+ if (GET_CODE(XEXP(x, 1)) == CONST_INT)
-+ return _amiga_is_const_pic_ref(XEXP(x, 0));
-+ return false;
-+ }
-+
-+ if (GET_CODE(x) == CONST)
-+ x = XEXP(x, 0);
-+ if (GET_CODE(x) != PLUS)
-+ return false;
-+
-+ const_rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg) && REGNO(reg) != PIC_REG)
-+ return false;
-+
-+ const_rtx unspec = XEXP(x, 1);
-+ while (GET_CODE(unspec) == PLUS || GET_CODE(unspec) == CONST)
-+ unspec = XEXP(unspec, 0);
-+
-+ if (GET_CODE(unspec) != UNSPEC)
-+ return false;
-+
-+ return true;
-+}
-+
-+int
-+amiga_is_const_pic_ref (const_rtx cnst)
-+{
-+ if (flag_pic < 3)
-+ return false;
-+ int r = _amiga_is_const_pic_ref (cnst);
-+// fprintf(stderr, r ? "valid pic: " : "invalid pic: ");
-+// debug_rtx(cnst);
-+ return r;
-+}
-+
-+
-+/* Does operand (which is a symbolic_operand) live in text space? If
-+ so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.
-+
-+ This function is used in base relative code generation. */
-+
-+int
-+read_only_operand (rtx operand)
-+{
-+ if (GET_CODE (operand) == CONST)
-+ operand = XEXP(XEXP (operand, 0), 0);
-+ if (GET_CODE (operand) == SYMBOL_REF)
-+ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
-+ return 1;
-+}
-+
-+rtx
-+amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
-+{
-+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
-+}
-+
-+rtx
-+amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
-+{
-+ if (!decl || !DECL_STATIC_CHAIN(decl))
-+ return 0;
-+
-+ unsigned used = 0;
-+ tree fntype = TREE_TYPE(decl);
-+ if (fntype)
-+ for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type =
TREE_CHAIN(formal_type))
-+ {
-+ tree asmtree = TYPE_ATTRIBUTES(TREE_VALUE(formal_type));
-+ if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ continue;
-+
-+ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ used |= 1 << regno;
-+ }
-+
-+ if (!(used & (1 << 9)))
-+ return gen_rtx_REG (Pmode, 9);
-+ if (!(used & (1 << 10)))
-+ return gen_rtx_REG (Pmode, 10);
-+ if (!(used & (1 << 11)))
-+ return gen_rtx_REG (Pmode, 11);
-+ if (!(used & (1 << 14)))
-+ return gen_rtx_REG (Pmode, 14);
-+
-+ return 0;
-+}
-+
-+/**
-+ * Necessary to block some funny invalid combinations if baserel is used:
-+ *
-+(const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+
-+(plus:SI (reg:SI 10 a2)
-+ (const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea}
-+
-+ */
-+bool
-+amigaos_legitimate_src (rtx src)
-+{
-+ if (flag_pic < 3)
-+ return true;
-+
-+ if (MEM_P(src))
-+ {
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS) {
-+ if (amiga_is_const_pic_ref(XEXP(x, 0))
-+ || amiga_is_const_pic_ref(XEXP(x, 1)))
-+ return false;
-+ }
-+ return true;
-+ }
-+
-+ if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
-+ {
-+ rtx x = XEXP(src, 0);
-+ rtx y = XEXP(src, 1);
-+
-+ /** handled in print_operand_address(...) */
-+ if (amiga_is_const_pic_ref(x))
-+ return GET_CODE(y) == CONST_INT;
-+
-+ return amigaos_legitimate_src(x) && amigaos_legitimate_src(y) &&
!amiga_is_const_pic_ref(y);
-+ }
-+
-+ if (GET_CODE(src) == CONST)
-+ {
-+ rtx op = XEXP(src, 0);
-+ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS)
-+ {
-+ rtx x = XEXP(op, 0);
-+ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG || GET_CODE(x) == SIGN_EXTEND)
-+ {
-+ rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg))
-+ return true;
-+
-+ return false;
-+ }
-+ }
-+
-+ if (GET_CODE(op) == UNSPEC)
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+void
-+amigaos_restore_a4 (void)
-+ {
-+ if (flag_pic >= 3 && !flag_resident)
-+ {
-+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
-+ tree attr = lookup_attribute ("saveds", attrs);
-+ if (attr || TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4)
-+ {
-+ rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___a4_init,a4",
DECL_SOURCE_LOCATION (current_function_decl));
-+ a4->volatil = 1;
-+ emit_insn(a4);
-+ }
-+ }
-+ }
-+
-+void
-+amigaos_alternate_frame_setup_f (int fsize)
-+ {
-+#if 0
-+ if (fsize < 128)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I%d,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\tlink %Ra5,%I%d:W\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")),
-+ fsize, -fsize);
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n",
-+ fsize);
-+#endif
-+ }
-+
-+void
-+amigaos_alternate_frame_setup (int fsize)
-+ {
-+#if 0
-+ if (!fsize)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I0,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")));
-+ else if (fsize < 128)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I%d,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\taddw %I%d,%Rsp\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")),
-+ fsize, -fsize);
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n",
-+ fsize);
-+#endif
-+ }
-+
-+#if 0
-+extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands)
-+{
-+ fprintf(stderr, "%s: %d ", txt, which_alternative);
-+ for (int i = 0; i < n; ++i)
-+ print_rtl(stderr, operands[i]);
-+ fprintf(stderr, "\n--\n");
-+ return true;
-+}
-+#endif
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-new file mode 100644
-index 000000000000..1b60ed633a3a
---- /dev/null
-+++ gcc/config/m68k/amigaos.h
-@@ -0,0 +1,504 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ *
-+ * This file is only included and used inside m68k.c to define the target.
-+ *
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#ifndef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+#endif
-+
-+#if 0
-+/* The function name __transfer_from_trampoline is not actually used.
-+ The function definition just permits use of asm with operands"
-+ (though the operand list is empty). */
-+
-+#undef TRANSFER_FROM_TRAMPOLINE
-+
-+/* Call __flush_cache() after building the trampoline: it will call
-+ an appropriate OS cache-clearing routine. */
-+
-+#undef FINALIZE_TRAMPOLINE
-+#define FINALIZE_TRAMPOLINE(TRAMP) \
-+ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__flush_cache"), \
-+ 0, VOIDmode, 2, (TRAMP), Pmode, \
-+ GEN_INT (TRAMPOLINE_SIZE), SImode)
-+
-+#endif
-+
-+/* Compile using the first 'm68k_regparm' data, address and float
-+ registers for arguments passing. */
-+/*#define SUBTARGET_OPTIONS { "regparm=", &m68k_regparm_string, \
-+ N_("Use this register count to pass arguments"), 0},*/
-+
-+
-+/* Nonzero if we need to generate special stack-allocating insns.
-+ On most systems they are not needed.
-+ When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md)
-+ to perform the necessary actions. */
-+//#undef TARGET_ALTERNATE_ALLOCATE_STACK
-+//#define TARGET_ALTERNATE_ALLOCATE_STACK 0
-+
-+
-+/* Compile with stack extension. */
-+
-+#define MASK_STACKEXTEND 0x40000000 /* 1 << 30 */
-+#define TARGET_STACKEXTEND (((target_flags & MASK_STACKEXTEND) \
-+ && !lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \
-+ || lookup_attribute ("stackext", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-+
-+///* Compile with stack checking. */
-+//
-+#define MASK_STACKCHECK 0x20000000 /* 1 << 29 */
-+#define TARGET_STACKCHECK ((target_flags & MASK_STACKCHECK) \
-+ && !(target_flags & MASK_STACKEXTEND) \
-+ && !lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \
-+ && !lookup_attribute ("stackext", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-+
-+/* Compile with a4 restoring in public functions. */
-+
-+#define MASK_RESTORE_A4 0x10000000 /* 1 << 28 */
-+#define TARGET_RESTORE_A4 \
-+ ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl))
-+
-+/* Compile with a4 restoring in all functions. */
-+
-+#define MASK_ALWAYS_RESTORE_A4 0x8000000 /* 1 << 27 */
-+#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4)
-+
-+/* Provide a dummy entry for the '-msmall-code' switch. This is used by
-+ the assembler and '*_SPEC'. */
-+
-+#undef SUBTARGET_SWITCHES
-+#define SUBTARGET_SWITCHES \
-+ { "small-code", 0, \
-+ "" /* Undocumented. */ }, \
-+ { "stackcheck", MASK_STACKCHECK, \
-+ N_("Generate stack-check code") }, \
-+ { "no-stackcheck", - MASK_STACKCHECK, \
-+ N_("Do not generate stack-check code") }, \
-+ { "stackextend", MASK_STACKEXTEND, \
-+ N_("Generate stack-extension code") }, \
-+ { "no-stackextend", - MASK_STACKEXTEND, \
-+ N_("Do not generate stack-extension code") }, \
-+ { "fixedstack", - (MASK_STACKCHECK|MASK_STACKEXTEND), \
-+ N_("Do not generate stack-check/stack-extension code") }, \
-+ { "restore-a4", MASK_RESTORE_A4, \
-+ N_("Restore a4 in public functions") }, \
-+ { "no-restore-a4", - MASK_RESTORE_A4, \
-+ N_("Do not restore a4 in public functions") }, \
-+ { "always-restore-a4", MASK_ALWAYS_RESTORE_A4, \
-+ N_("Restore a4 in all functions") }, \
-+ { "no-always-restore-a4", - MASK_ALWAYS_RESTORE_A4, \
-+ N_("Do not restore a4 in all functions") }
-+
-+
-+/* Support sections in chip, fast memory, currently '.datachip',
'.datafast'
-+ * and '.datafar' to abs addressing with baserel. */
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl);
-+
-+#undef TARGET_ASM_NAMED_SECTION
-+#define TARGET_ASM_NAMED_SECTION amiga_named_section
-+
-+/* Various ABI issues. */
-+
-+/* This is (almost;-) BSD, so it wants DBX format. */
-+#undef DBX_DEBUGGING_INFO
-+#define DBX_DEBUGGING_INFO
-+
-+/* GDB goes mad if it sees the function end marker. */
-+
-+#define NO_DBX_FUNCTION_END 1
-+
-+/* Allow folding division by zero. */
-+
-+#define REAL_INFINITY
-+
-+/* Don't try using XFmode since we don't have appropriate runtime software
-+ support. */
-+#undef LONG_DOUBLE_TYPE_SIZE
-+#define LONG_DOUBLE_TYPE_SIZE 64
-+
-+/* We use A4 for the PIC pointer, not A5, which is the framepointer. */
-+
-+#undef PIC_OFFSET_TABLE_REGNUM
-+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
-+
-+/* Use A5 as framepointer instead of A6, since the AmigaOS ABI requires A6
-+ to be used as a shared library base pointer in direct library calls. */
-+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
-+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) (reg_names[(r)])
-+
-+/* The AmigaOS ABI does not define how structures should be returned, so,
-+ contrary to 'm68k.h', we prefer a multithread-safe solution. */
-+
-+#undef PCC_STATIC_STRUCT_RETURN
-+
-+/* Setup a default shell return value for those (gazillion..) programs that
-+ (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus
-+ cause the shell to randomly caugh upon executing such programs (contrary
-+ to Unix, AmigaOS scripts are terminated with an error if a program returns
-+ with an error code above the `error' or even `failure' level
-+ (which is configurable with the FAILAT command)). */
-+
-+//+2004-06-24 Ulrich Weigand <uweigand(a)de.ibm.com>
-+//+
-+//+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN.
-+//+ * system.h (DEFAULT_MAIN_RETURN): Poison.
-+//+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation.
-+//+
-+
-+//poison VAR
-+//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-+
-+#undef WCHAR_TYPE
-+#define WCHAR_TYPE "unsigned short"
-+
-+/* XXX: section support */
-+#if 0
-+/* We define TARGET_ASM_NAMED_SECTION, but we don't support arbitrary sections,
-+ including '.gcc_except_table', so we emulate the standard behaviour. */
-+#undef TARGET_ASM_EXCEPTION_SECTION
-+#define TARGET_ASM_EXCEPTION_SECTION amiga_exception_section
-+
-+#undef TARGET_ASM_EH_FRAME_SECTION
-+#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section
-+#endif
-+
-+/* Use sjlj exceptions because dwarf work only on elf targets */
-+#undef DWARF2_UNWIND_INFO
-+#define DWARF2_UNWIND_INFO 0
-+
-+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
-+
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
-+
-+/* GAS supports alignment up to 32768 bytes. */
-+#undef ASM_OUTPUT_ALIGN
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+do \
-+ { \
-+ if ((LOG) == 1) \
-+ fprintf ((FILE), "\t.even\n"); \
-+ else \
-+ fprintf ((FILE), "\t.align %d\n", (LOG)); \
-+ } \
-+while (0)
-+
-+#if 0
-+
-+/* Define this macro if references to a symbol must be treated
-+ differently depending on something about the variable or
-+ function named by the symbol (such as what section it is in).
-+
-+ The macro definition, if any, is executed immediately after the
-+ rtl for DECL or other node is created.
-+ The value of the rtl will be a `mem' whose address is a
-+ `symbol_ref'.
-+
-+ The usual thing for this macro to do is to a flag in the
-+ `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
-+ name string in the `symbol_ref' (if one bit is not enough
-+ information).
-+
-+ On the Amiga we use this to indicate if references to a symbol should be
-+ absolute or base relative. */
-+
-+#undef TARGET_ENCODE_SECTION_INFO
-+#define TARGET_ENCODE_SECTION_INFO amigaos_encode_section_info
-+
-+#define LIBCALL_ENCODE_SECTION_INFO(FUN) \
-+do \
-+ { \
-+ if (flag_pic >= 3) \
-+ SYMBOL_REF_FLAG (FUN) = 1; \
-+ } \
-+while (0)
-+
-+/* Select and switch to a section for EXP. */
-+
-+//#undef TARGET_ASM_SELECT_SECTION
-+//#define TARGET_ASM_SELECT_SECTION amigaos_select_section
-+
-+/* Preserve A4 for baserel code if necessary. */
-+
-+#define EXTRA_SAVE_REG(REGNO) \
-+do { \
-+ if (flag_pic && flag_pic >= 3 && REGNO ==
PIC_OFFSET_TABLE_REGNUM \
-+ && amigaos_restore_a4()) \
-+ return true; \
-+} while (0)
-+
-+/* Predicate for ALTERNATE_PIC_SETUP. */
-+
-+#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3)
-+
-+/* Make a4 point at data hunk. */
-+
-+#define ALTERNATE_PIC_SETUP(STREAM) \
-+ (amigaos_alternate_pic_setup (STREAM))
-+
-+/* Attribute support. */
-+
-+/* Generate the test of d0 before return to set cc register in 'interrupt'
-+ function. */
-+
-+#define EPILOGUE_END_HOOK(STREAM) \
-+do \
-+ { \
-+ if (lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \
-+ asm_fprintf ((STREAM), "\ttstl %Rd0\n"); \
-+ } \
-+while (0)
-+
-+
-+/* Stack checking and automatic extension support. */
-+
-+#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \
-+ (amigaos_prologue_begin_hook ((STREAM), (FSIZE)))
-+
-+#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \
-+ (TARGET_STACKEXTEND && current_function_calls_alloca)
-+
-+#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \
-+ (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n"))
-+
-+#define HAVE_ALTERNATE_RETURN \
-+ (TARGET_STACKEXTEND && frame_pointer_needed && \
-+ current_function_calls_alloca)
-+
-+#define ALTERNATE_RETURN(STREAM)
-+
-+#if 0
-+#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND
-+#define gen_restore_stack_nonlocal gen_stack_cleanup_call
-+
-+#define HAVE_restore_stack_function TARGET_STACKEXTEND
-+#define gen_restore_stack_function gen_stack_cleanup_call
-+
-+#define HAVE_restore_stack_block TARGET_STACKEXTEND
-+#define gen_restore_stack_block gen_stack_cleanup_call
-+
-+#undef TARGET_ALTERNATE_ALLOCATE_STACK
-+#define TARGET_ALTERNATE_ALLOCATE_STACK 1
-+
-+#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \
-+do \
-+ { \
-+ amigaos_alternate_allocate_stack (OPERANDS); \
-+ DONE; \
-+ } \
-+while (0)
-+#endif
-+
-+/* begin-GG-local: dynamic libraries */
-+
-+extern int amigaos_do_collecting (void);
-+extern void amigaos_gccopts_hook (const char *);
-+extern void amigaos_libname_hook (const char* arg);
-+extern void amigaos_collect2_cleanup (void);
-+extern void amigaos_prelink_hook (const char **, int *);
-+extern void amigaos_postlink_hook (const char *);
-+
-+/* This macro is used to check if all collect2 facilities should be used.
-+ We need a few special ones, like stripping after linking. */
-+
-+#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new
-+
-+/* This macro is called in collect2 for every GCC argument name.
-+ ARG is a part of commandline (without '\0' at the end). */
-+
-+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
-+
-+/* This macro is called in collect2 for every ld's "-l" or "*.o"
or "*.a"
-+ argument. ARG is a complete argument, with '\0' at the end. */
-+
-+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
-+
-+/* This macro is called at collect2 exit, to clean everything up. */
-+
-+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
-+
-+/* This macro is called just before the first linker invocation.
-+ LD1_ARGV is "char** argv", which will be passed to "ld". STRIP
is an
-+ *address* of "strip_flag" variable. */
-+
-+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
-+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
-+
-+/* This macro is called just after the first linker invocation, in place of
-+ "nm" and "ldd". OUTPUT_FILE is the executable's filename.
*/
-+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
-+
-+#endif
-+
-+/* begin-GG-local: explicit register specification for parameters */
-+
-+/* Note: this is an extension of m68k_args */
-+
-+
-+#undef CLASS_MAX_NREGS
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((CLASS) == FP_REGS ? GET_MODE_NUNITS (MODE) \
-+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-+
-+
-+/*
-+ On the m68k, this is a structure:
-+ num_of_regs: number of data, address and float registers to use for
-+ arguments passing (if it's 2, than pass arguments in d0, d1, a0, a1,
-+ fp0 and fp1). 0 - pass everything on stack. vararg calls are
-+ always passed entirely on stack.
-+ regs_already_used: bitmask of the already used registers.
-+ last_arg_reg - register number of the most recently passed argument.
-+ -1 if passed on stack.
-+ last_arg_len - number of registers used by the most recently passed
-+ argument.
-+*/
-+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *cum, tree);
-+extern void amigaos_function_arg_advance (cumulative_args_t, machine_mode, const_tree,
bool);
-+extern rtx amigaos_function_arg (cumulative_args_t, machine_mode, const_tree, bool);
-+extern cumulative_args_t amigaos_pack_cumulative_args (CUMULATIVE_ARGS *);
-+extern int amigaos_comp_type_attributes (const_tree, const_tree);
-+extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
-+
-+/* Update the data in CUM to advance over an argument
-+ of mode MODE and data type TYPE.
-+ (TYPE is null for libcalls where that information may not be available.) */
-+
-+#undef TARGET_FUNCTION_ARG_ADVANCE
-+#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance
-+
-+/* A C expression that controls whether a function argument is passed
-+ in a register, and which register. */
-+
-+#undef TARGET_FUNCTION_ARG
-+#define TARGET_FUNCTION_ARG amigaos_function_arg
-+
-+#undef TARGET_PACK_CUMULATIVE_ARGS
-+#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \
-+ (amigaos_pack_cumulative_args(&(CUM)))
-+
-+#undef TARGET_COMP_TYPE_ATTRIBUTES
-+#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes
-+
-+
-+/* end-GG-local */
-+
-+#undef SUBTARGET_OVERRIDE_OPTIONS
-+#define SUBTARGET_OVERRIDE_OPTIONS \
-+do \
-+ { \
-+ if (flag_resident) \
-+ { \
-+ if (flag_pic) \
-+ error ("-fbaserel and -resident are mutual exclusiv\n"); \
-+ flag_pic = flag_resident; \
-+ } \
-+ if (!TARGET_68020 && flag_pic==4) \
-+ error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
-+ if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
-+ error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM);
\
-+ } \
-+while (0)
-+
-+/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-+ affects_type_identity } */
-+#define SUBTARGET_ATTRIBUTES \
-+ { "asmregs", 0, 0, false, false, false, 0, true }, \
-+ { "chip", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "fast", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "far", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false },
\
-+ { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
-+ true }, \
-+ { "stkparm", 0, 0, false, true, true, amigaos_handle_type_attribute,\
-+ true },
-+
-+#define GOT_SYMBOL_NAME ""
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS amigaos_rtx_costs
-+bool
-+amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+
-+#undef TARGET_STRUCT_VALUE_RTX
-+#define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx
-+rtx
-+amigaos_struct_value_rtx(tree fntype,
-+ int incoming ATTRIBUTE_UNUSED);
-+
-+#undef TARGET_STATIC_CHAIN
-+#define TARGET_STATIC_CHAIN amigaos_static_chain_rtx
-+rtx
-+amigaos_static_chain_rtx(const_tree fntype,
-+ bool incoming ATTRIBUTE_UNUSED);
-+
-+
-+extern bool
-+amigaos_legitimate_src (rtx src);
-+
-+extern void
-+amigaos_restore_a4 (void);
-+
-+extern void
-+amigaos_alternate_frame_setup_f (int fsize);
-+
-+extern void
-+amigaos_alternate_frame_setup (int fsize);
-+
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP_F(FSIZE) \
-+ (amigaos_alternate_frame_setup_f ((FSIZE)))
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP(FSIZE) \
-+ (amigaos_alternate_frame_setup ((FSIZE)))
-+
-+#undef TARGET_INSERT_ATTRIBUTES
-+#define TARGET_INSERT_ATTRIBUTES amiga_insert_attribute
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr);
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-new file mode 100644
-index 000000000000..07406d27a777
---- /dev/null
-+++ gcc/config/m68k/amigaos.opt
-@@ -0,0 +1,63 @@
-+
-+mregparm=
-+Target RejectNegative Var(amigaos_regparm) Joined UInteger Init(-1)
-+Pass arguments through registers.
-+
-+noixemul
-+Target RejectNegative
-+Do not use ixemul.library - use libnix instead to link
-+
-+ramiga-lib
-+Target RejectNegative
-+Use libinit.o as start file
-+
-+ramiga-libr
-+Target RejectNegative
-+Use libinitr.o as start file
-+
-+ramiga-dev
-+Target RejectNegative
-+Use devinit.o as start file
-+
-+msmall-code
-+Target RejectNegative Var(flag_smallcode,1)
-+small code model
-+
-+fbaserel
-+Target Report Var(flag_pic,3)
-+data is addressed relative to a4
-+
-+fbaserel32
-+Target Report Var(flag_pic,4)
-+data is addressed relative to a4 with 32 bit offsets
-+
-+resident
-+Target Common Report Var(flag_resident,3)
-+data is addressed relative to a4, linked as resident
-+
-+resident32
-+Target Common Report Var(flag_resident,4)
-+data is addressed relative to a4 with 32 bit offsets, linked as resident
-+
-+mcrt=
-+Target RejectNegative Var(amigaos_crt) Joined
-+Specify startup binary
-+
-+fbbb=
-+Target RejectNegative Report Var(string_bbb_opts) Joined
-+-fbbb=Enable Bebbo's optimizations.
-++ enable all optimizations
-+a commute add move instructions
-+b use register for base addresses
-+c convert load const and compare into a sub
-+e eliminate dead assignments + redundant loads
-+f shrink stack frame
-+i use post increment on addresses
-+m merge add and move statements
-+p propagate move assignment pairs out of loops
-+r register renaming to maybe save registers
-+s a strcpy optimization
-+v be verbose
-+V be very verbose
-+x dump insns
-+Default: -fbbb=+ which yields -fbbb=abcefimprs
-diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
-index b62120895304..1223852570c1 100644
---- gcc/config/m68k/constraints.md
-+++ gcc/config/m68k/constraints.md
-@@ -1,5 +1,5 @@
- ;; Constraint definitions for m68k
--;; Copyright (C) 2007-2016 Free Software Foundation, Inc.
-+;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
-
- ;; This file is part of GCC.
-
-diff --git a/gcc/config/m68k/host-amigaos.c b/gcc/config/m68k/host-amigaos.c
-new file mode 100755
-index 000000000000..8c72d516a378
---- /dev/null
-+++ gcc/config/m68k/host-amigaos.c
-@@ -0,0 +1,42 @@
-+/* AmigaOS/m68k host-specific hook definitions.
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "hosthooks.h"
-+#include "hosthooks-def.h"
-+#include "toplev.h"
-+
-+static void * amigaos_m68k_gt_pch_get_address (size_t);
-+
-+/* Return the address of the PCH address space, if the PCH will fit in it. */
-+
-+static void *
-+amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
-+{
-+ fatal_error ("PCH not supported\n");
-+}
-+
-+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
-+#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address
-+
-+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
-\ No newline at end of file
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 03f474e1b63c..4533427db7a7 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -166,7 +166,10 @@ static bool m68k_save_reg (unsigned int regno, bool
interrupt_handler);
- static bool m68k_ok_for_sibcall_p (tree, tree);
- static bool m68k_tls_symbol_p (rtx);
- static rtx m68k_legitimize_address (rtx, rtx, machine_mode);
--static bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+#ifndef TARGET_AMIGA
-+static
-+#endif
-+bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
- static bool m68k_return_in_memory (const_tree, const_tree);
- #endif
-@@ -174,10 +177,12 @@ static void m68k_output_dwarf_dtprel (FILE *, int, rtx)
ATTRIBUTE_UNUSED;
- static void m68k_trampoline_init (rtx, tree, rtx);
- static int m68k_return_pops_args (tree, tree, int);
- static rtx m68k_delegitimize_address (rtx);
-+#ifndef TARGET_AMIGA
- static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
- const_tree, bool);
- static rtx m68k_function_arg (cumulative_args_t, machine_mode,
- const_tree, bool);
-+#endif
- static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
- static bool m68k_output_addr_const_extra (FILE *, rtx);
- static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-@@ -186,7 +191,11 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-
- #if INT_OP_GROUP == INT_OP_DOT_WORD
- #undef TARGET_ASM_ALIGNED_HI_OP
-+#ifndef TARGET_AMIGAOS_VASM
- #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-+#else
-+#define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
-+#endif
- #endif
-
- #if INT_OP_GROUP == INT_OP_NO_DOT
-@@ -322,6 +331,10 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
- #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
- #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
-
-+#ifdef TARGET_AMIGA
-+#include "amigaos.h"
-+#endif
-+
- static const struct attribute_spec m68k_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-@@ -332,6 +345,9 @@ static const struct attribute_spec m68k_attribute_table[] =
- m68k_handle_fndecl_attribute, false },
- { "interrupt_thread", 0, 0, true, false, false,
- m68k_handle_fndecl_attribute, false },
-+#ifdef SUBTARGET_ATTRIBUTES
-+ SUBTARGET_ATTRIBUTES
-+#endif
- { NULL, 0, 0, false, false, false, NULL, false }
- };
-
-@@ -340,11 +356,21 @@ struct gcc_target targetm = TARGET_INITIALIZER;
- /* Base flags for 68k ISAs. */
- #define FL_FOR_isa_00 FL_ISA_68000
- #define FL_FOR_isa_10 (FL_FOR_isa_00 | FL_ISA_68010)
--/* FL_68881 controls the default setting of -m68881. gcc has traditionally
-+/* "FL_68881 controls the default setting of -m68881. gcc has traditionally
- generated 68881 code for 68020 and 68030 targets unless explicitly told
-- not to. */
-+ not to."
-+
-+ This is not true at least for the AMIGA.
-+ gcc 2.93 does not set the 68881 flag.
-+
-+ */
-+#ifdef TARGET_AMIGA
-+#define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
-+ | FL_BITFIELD | FL_CAS)
-+#else
- #define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
- | FL_BITFIELD | FL_68881 | FL_CAS)
-+#endif
- #define FL_FOR_isa_40 (FL_FOR_isa_20 | FL_ISA_68040)
- #define FL_FOR_isa_cpu32 (FL_FOR_isa_10 | FL_ISA_68020)
-
-@@ -545,7 +571,7 @@ m68k_option_override (void)
- : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE
- : FPUTYPE_68881);
-
-- /* Sanity check to ensure that msep-data and mid-sahred-library are not
-+ /* Sanity check to ensure that msep-data and mid-shared-library are not
- * both specified together. Doing so simply doesn't make sense.
- */
- if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
-@@ -556,7 +582,7 @@ m68k_option_override (void)
- * -fpic but it hasn't been tested properly.
- */
- if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
-- flag_pic = 2;
-+ flag_pic = TARGET_68020 ? 2 : 1;
-
- /* -mpcrel -fPIC uses 32-bit pc-relative displacements. Raise an
- error if the target does not support them. */
-@@ -569,11 +595,15 @@ m68k_option_override (void)
- if (TARGET_PCREL && flag_pic == 0)
- flag_pic = 1;
-
-- if (!flag_pic)
-+ /* SBF: use normal jumps/calls with baserel(32) modes. */
-+ if (!flag_pic || flag_pic > 2)
- {
- m68k_symbolic_call_var = M68K_SYMBOLIC_CALL_JSR;
--
-+#ifndef TARGET_AMIGAOS_VASM
- m68k_symbolic_jump = "jra %a0";
-+#else
-+ m68k_symbolic_jump = "jmp %a0";
-+#endif
- }
- else if (TARGET_ID_SHARED_LIBRARY)
- /* All addresses must be loaded from the GOT. */
-@@ -866,8 +896,9 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler)
- {
- if (crtl->saves_all_registers)
- return true;
-+ /* SBF: do not save the PIC_REG with baserel(32) modes. */
- if (crtl->uses_pic_offset_table)
-- return true;
-+ return flag_pic < 3;
- /* Reload may introduce constant pool references into a function
- that thitherto didn't need a PIC register. Note that the test
- above will not catch that case because we will only set
-@@ -978,6 +1009,8 @@ m68k_set_frame_related (rtx_insn *insn)
-
- /* Emit RTL for the "prologue" define_expand. */
-
-+extern void amiga_emit_regparm_clobbers(void);
-+
- void
- m68k_expand_prologue (void)
- {
-@@ -986,6 +1019,10 @@ m68k_expand_prologue (void)
-
- m68k_compute_frame_layout ();
-
-+#ifdef TARGET_AMIGA
-+ amiga_emit_regparm_clobbers();
-+#endif
-+
- if (flag_stack_usage_info)
- current_function_static_stack_size
- = current_frame.size + current_frame.offset;
-@@ -1021,6 +1058,11 @@ m68k_expand_prologue (void)
-
- if (frame_pointer_needed)
- {
-+#ifdef TARGET_AMIGA
-+ if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP_F (fsize_with_regs);
-+ else
-+#endif
- if (fsize_with_regs == 0 && TUNE_68040)
- {
- /* On the 68040, two separate moves are faster than link.w 0. */
-@@ -1030,6 +1072,10 @@ m68k_expand_prologue (void)
- m68k_set_frame_related (emit_move_insn (frame_pointer_rtx,
- stack_pointer_rtx));
- }
-+#ifdef TARGET_AMIGA
-+ else if (HAVE_ALTERNATE_FRAME_SETUP (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP (fsize_with_regs);
-+#endif
- else if (fsize_with_regs < 0x8000 || TARGET_68020)
- m68k_set_frame_related
- (emit_insn (gen_link (frame_pointer_rtx,
-@@ -1127,9 +1173,14 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
-+ /* SBF: do not load the PIC_REG with baserel(32) */
- if (!TARGET_SEP_DATA
-- && crtl->uses_pic_offset_table)
-+ && crtl->uses_pic_offset_table && flag_pic < 3)
- emit_insn (gen_load_got (pic_offset_table_rtx));
-+
-+#ifdef TARGET_AMIGA
-+ amigaos_restore_a4 ();
-+#endif
- }
-
- /* Return true if a simple (return) instruction is sufficient for this
-@@ -1419,6 +1470,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
- return false;
- }
-
-+#ifndef TARGET_AMIGA
- /* On the m68k all args are always pushed. */
-
- static rtx
-@@ -1440,6 +1492,7 @@ m68k_function_arg_advance (cumulative_args_t cum_v, machine_mode
mode,
- ? (GET_MODE_SIZE (mode) + 3) & ~3
- : (int_size_in_bytes (type) + 3) & ~3);
- }
-+#endif
-
- /* Convert X to a legitimate function call memory reference and return the
- result. */
-@@ -1796,13 +1849,21 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn
*insn, int signpos
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- if (count == 2 && DATA_REG_P (operands[1])
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_INVERTED | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- /* count == 1 followed by bvc/bvs and
- count == 0 followed by bcc/bcs are also possible, but need
-@@ -1921,10 +1982,12 @@ m68k_legitimate_constant_address_p (rtx x, unsigned int reach,
bool strict_p)
- if (!CONSTANT_ADDRESS_P (x))
- return false;
-
-- if (flag_pic
-+ if (flag_pic && flag_pic < 3
- && !(strict_p && TARGET_PCREL)
- && symbolic_operand (x, VOIDmode))
-- return false;
-+ {
-+ return false;
-+ }
-
- if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1)
- {
-@@ -2111,6 +2174,18 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool
strict_p)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ if (MEM_P(x))
-+ return false;
-+ /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
-+ if (amiga_is_const_pic_ref(x))
-+ return true;
-+
-+ if (!amigaos_legitimate_src(x))
-+ return false;
-+
-+#endif
-+
- return m68k_decompose_address (mode, x, strict_p, &address);
- }
-
-@@ -2131,7 +2206,11 @@ m68k_legitimate_mem_p (rtx x, struct m68k_address *address)
- bool
- m68k_legitimate_constant_p (machine_mode mode, rtx x)
- {
-- return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x);
-+ return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x)
-+#ifdef TARGET_AMIGA
-+ && amigaos_legitimate_src (x)
-+#endif
-+ ;
- }
-
- /* Return true if X matches the 'Q' constraint. It must be a memory
-@@ -2172,6 +2251,8 @@ m68k_get_gp (void)
- if (pic_offset_table_rtx == NULL_RTX)
- pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
-
-+// debug_rtx(pic_offset_table_rtx);
-+
- crtl->uses_pic_offset_table = 1;
-
- return pic_offset_table_rtx;
-@@ -2442,9 +2523,37 @@ legitimize_pic_address (rtx orig, machine_mode mode
ATTRIBUTE_UNUSED,
- if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
- {
- gcc_assert (reg);
-+ if (flag_pic < 3)
-+ {
-+ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-+ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+ }
-+ #ifdef TARGET_AMIGA
-+ else
-+ {
-+
-+ /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
-+ * Do not ref to .text via pic_reg!
-+ */
-+ tree decl;
-+ if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related &&
!SYMBOL_REF_FUNCTION_P(orig)
-+ && (decl = SYMBOL_REF_DECL (orig)) && !(DECL_SECTION_NAME(decl))
-+ && !decl->common.typed.base.readonly_flag
-+ && !decl->decl_with_vis.in_text_section)
-+ {
-
-- pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-- pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+ /* SBF: unfortunately using the wrapped symbol without MEM does not work.
-+ * The pic_ref reference gets decomposed and leads to no working code.
-+ */
-+ pic_ref = m68k_wrap_symbol (pic_ref, RELOC_GOT, m68k_get_gp (), reg);
-+
-+ /* SBF: adding const avoids decomposing. */
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+ else
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+#endif
- }
- else if (GET_CODE (orig) == CONST)
- {
-@@ -2463,7 +2572,8 @@ legitimize_pic_address (rtx orig, machine_mode mode
ATTRIBUTE_UNUSED,
- orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
-
-- if (GET_CODE (orig) == CONST_INT)
-+ /* SBF: use normal plus and rely on optimizer with baserel(32). */
-+ if (flag_pic < 3 && GET_CODE (orig) == CONST_INT)
- pic_ref = plus_constant (Pmode, base, INTVAL (orig));
- else
- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
-@@ -2787,7 +2897,10 @@ const_int_cost (HOST_WIDE_INT i)
- }
- }
-
--static bool
-+#ifndef TARGET_AMIGA
-+static
-+#endif
-+bool
- m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- int opno ATTRIBUTE_UNUSED,
- int *total, bool speed ATTRIBUTE_UNUSED)
-@@ -2863,6 +2976,7 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
- return true;
- }
-+
- return false;
-
- case ASHIFT:
-@@ -2931,6 +3045,25 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = 0;
- return false;
-
-+ case MEM:
-+ {
-+ /* simple but not exact */
-+ rtx y = XEXP(x, 0);
-+ int yc = GET_CODE(y);
-+ if (yc == REG || yc == PRE_INC || yc == POST_INC || yc == POST_DEC)
-+ *total += 4;
-+ else
-+ if (yc == PRE_DEC)
-+ *total += 6;
-+ else
-+ *total += 8;
-+
-+ if (mode != QImode && mode != QImode)
-+ *total += 4;
-+
-+ return true;
-+ }
-+
- default:
- return false;
- }
-@@ -4456,7 +4589,9 @@ print_operand (FILE *file, rtx op, int letter)
- else if (letter == 'p')
- {
- output_addr_const (file, op);
-- if (!(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
-+ /* SBF: do not add @PLTPC with baserel(32). */
-+ if (flag_pic < 3
-+ && !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
- fprintf (file, "@PLTPC");
- }
- else if (GET_CODE (op) == REG)
-@@ -4475,34 +4610,52 @@ print_operand (FILE *file, rtx op, int letter)
- && CONSTANT_ADDRESS_P (XEXP (op, 0))
- && !(GET_CODE (XEXP (op, 0)) == CONST_INT
- && INTVAL (XEXP (op, 0)) < 0x8000
-- && INTVAL (XEXP (op, 0)) >= -0x8000))
-- fprintf (file, MOTOROLA ? ".l" : ":l");
-+ && INTVAL (XEXP (op, 0)) >= -0x8000)
-+#ifdef TARGET_AMIGA
-+/* SBF: Do not append some 'l' with baserel(32). */
-+ && !amiga_is_const_pic_ref(XEXP(op, 0))
-+#endif
-+ )
-+ fprintf (file, MOTOROLA ? ".l" : ":l");
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
- {
- long l;
- REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx", l & 0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx", l & 0xFFFFFFFF);
-+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
- {
- long l[3];
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
- l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
-+ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
-+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
- {
- long l[2];
- REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx", l[0] & 0xFFFFFFFF, l[1] &
0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] &
0xFFFFFFFF);
-+#endif
- }
- else
- {
- /* Use `print_operand_address' instead of `output_addr_const'
- to ensure that we print relevant PIC stuff. */
- asm_fprintf (file, "%I");
-- if (TARGET_PCREL
-+ if ((TARGET_PCREL || flag_pic > 2)
- && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
- print_operand_address (file, op);
- else
-@@ -4521,7 +4674,19 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
- switch (reloc)
- {
- case RELOC_GOT:
-- if (MOTOROLA)
-+ /* SBF: add the proper extension for baserel relocs with baserel(32). */
-+ if (TARGET_AMIGA)
-+ {
-+ if (flag_pic == 1)
-+ return ".w";
-+ else if (flag_pic == 3)
-+ return ":W";
-+ else if (flag_pic == 4)
-+ return ":L";
-+ else
-+ return "";
-+ }
-+ if (MOTOROLA)
- {
- if (flag_pic == 1 && TARGET_68020)
- return "(a)GOT.w";
-@@ -4671,8 +4836,58 @@ print_operand_address (FILE *file, rtx addr)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * SBF: remove the const wrapper.
-+ */
-+ if (amiga_is_const_pic_ref(addr))
-+ {
-+ /* handle (plus (unspec ) (const_int) */
-+ rtx *x = &addr;
-+ while (GET_CODE(*x) != PLUS)
-+ x = &XEXP(*x, 0);
-+
-+ x = &XEXP(*x, 1); // CONST
-+ if (GET_CODE(*x) == CONST)
-+ x = &XEXP(*x, 0);
-+
-+ /* if there is a plus - swap it.
-+ * we want n+symbol:W (not symbol:W+n)
-+ */
-+ if (GET_CODE(*x) == PLUS)
-+ {
-+ rtx plus = *x;
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(plus, 1)));
-+
-+ *x = XEXP(plus, 0);
-+ print_operand_address(file, XEXP(addr, 0));
-+ *x = plus;
-+ }
-+ else
-+ print_operand_address(file, XEXP(addr, 0));
-+
-+ return;
-+ }
-+ if (GET_CODE(addr) == PLUS && amiga_is_const_pic_ref(XEXP(addr, 0)))
-+ {
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(addr, 1)));
-+ print_operand_address(file, XEXP(XEXP(addr, 0),0));
-+ return;
-+ }
-+
-+
-+ if (symbolic_operand(addr, VOIDmode))
-+ {
-+ memset (&address, 0, sizeof (address));
-+ address.offset = addr;
-+ }
-+ else
-+#endif
- if (!m68k_decompose_address (QImode, addr, true, &address))
-- gcc_unreachable ();
-+ {
-+ debug_rtx(addr);
-+ gcc_unreachable ();
-+ }
-
- if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
-@@ -4714,6 +4929,14 @@ print_operand_address (FILE *file, rtx addr)
- }
- else
- output_addr_const (file, addr);
-+
-+#ifdef TARGET_AMIGA
-+ if (SYMBOL_REF_FUNCTION_P(addr))
-+ {
-+ if (flag_smallcode)
-+ asm_fprintf(file, ":w(pc)");
-+ }
-+#endif
- }
- }
- else
-@@ -5155,7 +5378,9 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
-
- /* Value is true if hard register REGNO can hold a value of machine-mode
- MODE. On the 68000, we let the cpu registers can hold any mode, but
-- restrict the 68881 registers to floating-point modes. */
-+ restrict the 68881 registers to floating-point modes.
-+ SBF: Disallow the frame pointer register, if the frame pointer is used.
-+ */
-
- bool
- m68k_regno_mode_ok (int regno, machine_mode mode)
-@@ -5169,7 +5394,7 @@ m68k_regno_mode_ok (int regno, machine_mode mode)
- else if (ADDRESS_REGNO_P (regno))
- {
- if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
-- return true;
-+ return !frame_pointer_needed || regno != FRAME_POINTER_REGNUM;
- }
- else if (FP_REGNO_P (regno))
- {
-@@ -5190,6 +5415,13 @@ m68k_secondary_reload_class (enum reg_class rclass,
- machine_mode mode, rtx x)
- {
- int regno;
-+#ifdef TARGET_AMIGA
-+ /* SBF: check for baserel's const pic_ref
-+ * and return ADDR_REGS or NO_REGS
-+ */
-+ if (!MEM_P(x) && amiga_is_const_pic_ref(x))
-+ return rclass == ADDR_REGS ? NO_REGS : ADDR_REGS;
-+#endif
-
- regno = true_regnum (x);
-
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 2aa858fa23b5..442a84e6a883 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -204,7 +204,11 @@ along with GCC; see the file COPYING3. If not see
- #define INT_OP_DC 3 /* dc.b, dc.w, dc.l */
-
- /* Set the default. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define INT_OP_GROUP INT_OP_DOT_WORD
-+#else
-+#define INT_OP_GROUP INT_OP_DC
-+#endif
-
- /* Bit values used by m68k-devices.def to identify processor capabilities. */
- #define FL_BITFIELD (1 << 0) /* Support bitfield instructions. */
-@@ -378,14 +382,13 @@ along with GCC; see the file COPYING3. If not see
- { /* d0/d1/a0/a1 */ \
- 0, 1, 8, 9, \
- /* d2-d7 */ \
-- 2, 3, 4, 5, 6, 7, \
-+ 2, 10, 3, 11, 4, 5, 6, 7, \
- /* a2-a7/arg */ \
-- 10, 11, 12, 13, 14, 15, 24, \
-+ 12, 13, 14, 15, 24, \
- /* fp0-fp7 */ \
- 16, 17, 18, 19, 20, 21, 22, 23\
- }
-
--
- /* On the m68k, ordinary registers hold 32 bits worth;
- for the 68881 registers, a single register is always enough for
- anything that can be stored in them at all. */
-@@ -440,8 +443,8 @@ along with GCC; see the file COPYING3. If not see
- /* The m68k has three kinds of registers, so eight classes would be
- a complete set. One of them is not needed. */
- enum reg_class {
-- NO_REGS, DATA_REGS,
-- ADDR_REGS, FP_REGS,
-+ NO_REGS, DATA_REGS, D0_REGS,
-+ ADDR_REGS, A0_REGS, FP_REGS,
- GENERAL_REGS, DATA_OR_FP_REGS,
- ADDR_OR_FP_REGS, ALL_REGS,
- LIM_REG_CLASSES };
-@@ -449,8 +452,8 @@ enum reg_class {
- #define N_REG_CLASSES (int) LIM_REG_CLASSES
-
- #define REG_CLASS_NAMES \
-- { "NO_REGS", "DATA_REGS", \
-- "ADDR_REGS", "FP_REGS", \
-+ { "NO_REGS", "DATA_REGS", "D0_REGS" \
-+ "ADDR_REGS", "A0_REGS", "FP_REGS", \
- "GENERAL_REGS", "DATA_OR_FP_REGS", \
- "ADDR_OR_FP_REGS", "ALL_REGS" }
-
-@@ -458,7 +461,9 @@ enum reg_class {
- { \
- {0x00000000}, /* NO_REGS */ \
- {0x000000ff}, /* DATA_REGS */ \
-+ {0x00000001}, /* D0_REGS */ \
- {0x0100ff00}, /* ADDR_REGS */ \
-+ {0x00000100}, /* A0_REGS */ \
- {0x00ff0000}, /* FP_REGS */ \
- {0x0100ffff}, /* GENERAL_REGS */ \
- {0x00ff00ff}, /* DATA_OR_FP_REGS */ \
-@@ -614,11 +619,11 @@ __transfer_from_trampoline () \
-
- #define REGNO_OK_FOR_INDEX_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-- || INT_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && INT_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_BASE_P(REGNO) \
- (ADDRESS_REGNO_P (REGNO) \
-- || ADDRESS_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && ADDRESS_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-@@ -727,9 +732,49 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- if (cc_prev_status.flags & CC_NO_OVERFLOW) \
- return NO_OV; \
- return NORMAL; } while (0)
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
-+ do { \
-+ FILE *_hide_asm_out_file = (MYFILE); \
-+ const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
-+ int _hide_thissize = (MYLENGTH); \
-+ { \
-+ FILE *asm_out_file = _hide_asm_out_file; \
-+ const unsigned char *p = _hide_p; \
-+ int thissize = _hide_thissize; \
-+ int i; \
-+ fprintf (asm_out_file, "\tdc.b \"");
\
-+ \
-+ for (i = 0; i < thissize; i++) \
-+ { \
-+ int c = p[i]; \
-+ if (c == '\"' || c == '\\')
\
-+ putc ('\\', asm_out_file); \
-+ if (ISPRINT (c)) \
-+ putc (c, asm_out_file); \
-+ else \
-+ { \
-+ fprintf (asm_out_file, "\\%o", c);
\
-+ /* After an octal-escape, if a digit follows, \
-+ terminate one string constant and start another. \
-+ The VAX assembler fails to stop reading the escape \
-+ after three digits, so this is the only way we \
-+ can get it to parse the data properly. */ \
-+ if (i < thissize - 1 && ISDIGIT (p[i + 1]))
\
-+ fprintf (asm_out_file, "\"\n\tdc.b \"");
\
-+ } \
-+ } \
-+ fprintf (asm_out_file, "\"\n");
\
-+ } \
-+ } \
-+ while (0)
-+#endif
-
-+
- /* Control the assembler format that we output. */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_APP_ON "#APP\n"
- #define ASM_APP_OFF "#NO_APP\n"
- #define TEXT_SECTION_ASM_OP "\t.text"
-@@ -739,6 +784,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- #define LOCAL_LABEL_PREFIX ""
- #define USER_LABEL_PREFIX "_"
- #define IMMEDIATE_PREFIX "#"
-+#else
-+#define ASM_APP_ON ""
-+#define ASM_APP_OFF ""
-+#define TEXT_SECTION_ASM_OP "\tsection .text"
-+#define DATA_SECTION_ASM_OP "\tsection .data"
-+#define GLOBAL_ASM_OP "\txdef\t"
-+#define REGISTER_PREFIX ""
-+#define LOCAL_LABEL_PREFIX "_."
-+#define USER_LABEL_PREFIX "_"
-+#define IMMEDIATE_PREFIX "#"
-+#endif
-
- #define REGISTER_NAMES \
- {REGISTER_PREFIX"d0", REGISTER_PREFIX"d1",
REGISTER_PREFIX"d2", \
-@@ -858,11 +914,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- /* The m68k does not use absolute case-vectors, but we must define this macro
- anyway. */
--#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- asm_fprintf (FILE, "\t.long %LL%d\n", VALUE)
--
--#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL)
-+#else
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+ asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
-+#endif
-
- /* We don't have a way to align to more than a two-byte boundary, so do the
- best we can and don't complain. */
-@@ -872,13 +934,24 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
- /* Use "move.l %a4,%a4" to advance within code. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
- if ((LOG) > 0) \
- fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
- #endif
-+#else
-+#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "\tcnop 0,%u\n", 1 << (LOG));
-+#endif
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
-+#else
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+ fprintf (FILE, "\tds.b %u\n", (int)(SIZE))
-+#endif
-
- #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
- ( fputs (".comm ", (FILE)), \
-@@ -971,3 +1044,8 @@ extern int m68k_sched_address_bypass_p (rtx_insn *, rtx_insn *);
- extern int m68k_sched_indexed_address_bypass_p (rtx_insn *, rtx_insn *);
-
- #define CPU_UNITS_QUERY 1
-+
-+#if 1
-+extern void default_stabs_asm_out_constructor (rtx, int);
-+extern void default_stabs_asm_out_destructor (rtx, int);
-+#endif
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index ec37bd76f55f..05ef02027f01 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -128,13 +128,11 @@
- (UNSPECV_TAS_2 4)
- ])
-
--;; Registers by name.
-+;; Registers by name. SBF: Do not define PIC_REG / A6_REG here!
- (define_constants
- [(D0_REG 0)
- (A0_REG 8)
- (A1_REG 9)
-- (PIC_REG 13)
-- (A6_REG 14)
- (SP_REG 15)
- (FP0_REG 16)
- ])
-@@ -1566,7 +1564,7 @@
- ;; so we will prefer it to them.
-
- (define_insn "pushasi"
-- [(set (match_operand:SI 0 "push_operand" "=m")
-+ [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "address_operand" "p"))]
- ""
- "pea %a1"
-@@ -7204,6 +7202,7 @@
- "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
-
- ;; Changing pea X.w into a move.l is no real win here.
-+;; SBF: also disable converting pea for baserel insns!
- (define_peephole2
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
- (match_operand:SI 0 "const_int_operand" "")))
-@@ -7213,7 +7212,8 @@
- && !reg_mentioned_p (stack_pointer_rtx, operands[2])
- && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
- && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
-- && !valid_mov3q_const (INTVAL (operands[2])))"
-+ && !valid_mov3q_const (INTVAL (operands[2])))
-+ && !amiga_is_const_pic_ref(operands[2])"
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
- (set (match_dup 1) (match_dup 2))]
- {
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-new file mode 100644
-index 000000000000..3f3aafc5f254
---- /dev/null
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -0,0 +1,760 @@
-+/* m68kelf support, derived from m68kv4.h */
-+
-+/* Target definitions for GNU compiler for mc680x0 running AmigaOs
-+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
-+
-+ Written by Ron Guilmette (rfg(a)netcom.com) and Fred Fish (fnf(a)cygnus.com).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 3, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3. If not see
-+<http://www.gnu.org/licenses/>. */
-+
-+#ifndef TARGET_AMIGA
-+#define TARGET_AMIGA 1
-+#endif
-+
-+#define HAS_INIT_SECTION
-+
-+#ifndef SWBEG_ASM_OP
-+#define SWBEG_ASM_OP "\t.swbeg\t"
-+#endif
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#undef ASM_STABS_OP
-+#define ASM_STABS_OP "|\t.stabs\t"
-+
-+#undef ASM_STABD_OP
-+#define ASM_STABD_OP "|\t.stabd\t"
-+
-+#undef ASM_STABN_OP
-+#define ASM_STABN_OP "|\t.stabn\t"
-+#endif
-+
-+#undef PIC_REG
-+#define PIC_REG 12
-+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
-+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) ( \
-+ ( ((r) == FRAME_POINTER_REGNUM) \
-+ && frame_pointer_needed) ? \
-+ M68K_FP_REG_NAME : reg_names[(r)])
-+
-+
-+
-+/* Here are three prefixes that are used by asm_fprintf to
-+ facilitate customization for alternate assembler syntaxes.
-+ Machines with no likelihood of an alternate syntax need not
-+ define these and need not use asm_fprintf. */
-+
-+/* The prefix for register names. Note that REGISTER_NAMES
-+ is supposed to include this prefix. Also note that this is NOT an
-+ fprintf format string, it is a literal string */
-+
-+#undef REGISTER_PREFIX
-+#define REGISTER_PREFIX ""
-+
-+/* The prefix for local (compiler generated) labels.
-+ These labels will not appear in the symbol table. */
-+
-+#undef LOCAL_LABEL_PREFIX
-+#ifndef TARGET_AMIGAOS_VASM
-+#define LOCAL_LABEL_PREFIX "."
-+#else
-+#define LOCAL_LABEL_PREFIX "_."
-+#endif
-+
-+/* The prefix to add to user-visible assembler symbols. */
-+
-+#undef USER_LABEL_PREFIX
-+#define USER_LABEL_PREFIX "_"
-+
-+/* config/m68k.md has an explicit reference to the program counter,
-+ prefix this by the register prefix. */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp %%pc@(2,%0:w)"; \
-+ } while (0)
-+#else
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp (2,pc,%0.w)"; \
-+ } while (0)
-+#endif
-+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
-+#else
-+#define ALIGN_ASM_OP "\talign\t"
-+#endif
-+
-+#undef ASM_OUTPUT_ALIGN
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
-+} while (0)
-+#else
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, (LOG)); \
-+} while (0)
-+#endif
-+
-+#if 0
-+extern int amiga_declare_object;
-+
-+#define ASM_DECLARE_OBJECT_NAME(FILE,NAME,DECL) \
-+if (!DECL_INITIAL (DECL) || \
-+ initializer_zerop (DECL_INITIAL (decl))) \
-+ { \
-+ amiga_declare_object = 1; \
-+ fprintf ((FILE), ".comm\t%s,", NAME); \
-+ } \
-+else \
-+ASM_OUTPUT_LABEL (FILE, NAME)
-+
-+#undef ASM_OUTPUT_SKIP
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+if (amiga_declare_object) \
-+ fprintf (FILE, "%u\n", (int)(SIZE)); \
-+else \
-+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE)); \
-+amiga_declare_object = 0
-+#endif
-+
-+/* Register in which address to store a structure value is passed to a
-+ function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */
-+
-+#undef M68K_STRUCT_VALUE_REGNUM
-+#define M68K_STRUCT_VALUE_REGNUM A0_REG
-+
-+/* The static chain regnum defaults to a0, but we use that for
-+ structure return, so have to use a1 for the static chain. */
-+
-+#undef STATIC_CHAIN_REGNUM
-+#define STATIC_CHAIN_REGNUM A1_REG
-+#undef M68K_STATIC_CHAIN_REG_NAME
-+#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1"
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_COMMENT_START "|"
-+#else
-+#define ASM_COMMENT_START "|"
-+#endif
-+
-+/* Define how the m68k registers should be numbered for Dwarf output.
-+ The numbering provided here should be compatible with the native
-+ SVR4 SDB debugger in the m68k/SVR4 reference port, where d0-d7
-+ are 0-7, a0-a8 are 8-15, and fp0-fp7 are 16-23. */
-+
-+#undef DBX_REGISTER_NUMBER
-+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-+
-+#if 0
-+/* SVR4 m68k assembler is bitching on the `comm i,1,1' which askes for
-+ 1 byte alignment. Don't generate alignment for COMMON seems to be
-+ safer until we the assembler is fixed. */
-+#undef ASM_OUTPUT_ALIGNED_COMMON
-+/* Same problem with this one. */
-+#undef ASM_OUTPUT_ALIGNED_LOCAL
-+#endif
-+
-+#undef ASM_OUTPUT_COMMON
-+#undef ASM_OUTPUT_LOCAL
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".comm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ ( switch_to_section (bss_section), \
-+ fputs ("|.comm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)), \
-+ fputs ("\txdef ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), "\n"))
-+#endif
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".lcomm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( switch_to_section (bss_section), \
-+ fputs ("|.lcomm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)))
-+#endif
-+
-+/* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
-+ keep switch tables in the text section. */
-+
-+#define JUMP_TABLES_IN_TEXT_SECTION 1
-+
-+/* In m68k svr4, using swbeg is the standard way to do switch
-+ table. */
-+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
-+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
-+ fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE),
1));
-+/* end of stuff from m68kv4.h */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#undef BSS_SECTION_ASM_OP
-+#define BSS_SECTION_ASM_OP "\t.bss"
-+#else
-+#define BSS_SECTION_ASM_OP "\tsection\tbss"
-+#endif
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#undef DATA_SECTION_ASM_OP
-+#define DATA_SECTION_ASM_OP "\t.data"
-+#else
-+#define DATA_SECTION_ASM_OP "\tsection\tdata"
-+#endif
-+
-+#ifndef ASM_OUTPUT_ALIGNED_BSS
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
-+#endif
-+
-+
-+/* Specs, switches. */
-+
-+/* amiga/amigaos are the new "standard" defines for the Amiga.
-+ MCH_AMIGA, AMIGA, __chip etc. are used in other compilers and are
-+ provided for compatibility reasons.
-+ When creating shared libraries, use different 'errno'. */
-+
-+#undef TARGET_OS_CPP_BUILTINS
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define ("__chip=__attribute__((__chip__))"); \
-+ builtin_define ("__fast=__attribute__((__fast__))"); \
-+ builtin_define ("__far=__attribute__((__far__))"); \
-+ builtin_define ("__saveds=__attribute__((__saveds__))"); \
-+ builtin_define ("__interrupt=__attribute__((__interrupt__))"); \
-+ builtin_define ("__stackext=__attribute__((__stackext__))"); \
-+ builtin_define ("__regargs=__attribute__((__regparm__(2)))"); \
-+ builtin_define ("__stdargs=__attribute__((__stkparm__))"); \
-+ builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
-+ builtin_define_std ("amiga"); \
-+ builtin_define_std ("amigaos"); \
-+ builtin_define_std ("AMIGA"); \
-+ builtin_define_std ("MCH_AMIGA"); \
-+ builtin_assert ("system=amigaos"); \
-+ } \
-+ while (0)
-+
-+#if 0
-+if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
-+ builtin_define ("errno=(*ixemul_errno)"); \
-+
-+#endif
-+
-+/* put return values in FPU build in FP0 Reg */
-+#undef FUNCTION_VALUE_REGNO_P
-+#define FUNCTION_VALUE_REGNO_P(N) \
-+ ((N) == D0_REG || (TARGET_68881 && (N) == FP0_REG))
-+
-+// see 930623-1.c
-+// ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG))
-+
-+/* Inform the program which CPU we compile for. */
-+
-+//#undef TARGET_CPU_CPP_BUILTINS
-+/*
-+ use --with-cpu=mc68040 etc.. instead on config. code was after #define
TARGET_CPU_CPP_BUILTINS()
-+ if (TARGET_68040_ONLY) \
-+ { \
-+ if (TARGET_68060) \
-+ builtin_define_std ("mc68060"); \
-+ else \
-+ builtin_define_std ("mc68040"); \
-+ } \
-+ else if (TARGET_68030 && !TARGET_68040) \
-+ builtin_define_std ("mc68030"); \
-+ else if (TARGET_68020) \
-+ builtin_define_std ("mc68020"); \
-+ builtin_define_std ("mc68000"); \
-+*/
-+/*
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("mc68040"); \
-+ if (flag_pic > 2) \
-+ { \
-+ builtin_define ("__pic__"); \
-+ if (flag_pic > 3) \
-+ builtin_define ("__PIC__"); \
-+ } \
-+ builtin_assert ("cpu=m68k"); \
-+ builtin_assert ("machine=m68k"); \
-+ } \
-+ while (0)
-+*/
-+
-+/* When creating shared libraries, use different 'errno'. */
-+#define CPP_IXEMUL_SPEC \
-+ "%{!ansi:-Dixemul} -D__ixemul__ -D__ixemul " \
-+ "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
-+ "%{mrestore-a4:-Derrno=(*ixemul_errno)}"
-+#define CPP_LIBNIX_SPEC \
-+ "-isystem %:sdk_root(libnix/include) " \
-+ "%{!ansi:-Dlibnix} -D__libnix__ -D__libnix"
-+#define CPP_CLIB2_SPEC \
-+ "-isystem %:sdk_root(clib2/include) " \
-+ "%{!ansi:-DCLIB2} -D__CLIB2__ -D__CLIB2"
-+
-+/* Define __HAVE_68881__ in preprocessor according to the -m flags.
-+ This will control the use of inline 68881 insns in certain macros.
-+ Note: it should be set in TARGET_CPU_CPP_BUILTINS but TARGET_68881
-+ isn't the same -m68881 since its also true for -m680[46]0 ...
-+ Differentiate between libnix and ixemul. */
-+
-+#define CPP_SPEC \
-+ "%{m68881:-D__HAVE_68881__} " \
-+ "%{!ansi:" \
-+ "%{m68020:-Dmc68020} " \
-+ "%{mc68020:-Dmc68020} " \
-+ "%{m68020-40:-Dmc68020} " \
-+ "%{m68020-60:-Dmc68020} " \
-+ "%{m68030:-Dmc68030} " \
-+ "%{m68040:-Dmc68040} " \
-+ "%{m68060:-Dmc68060}} " \
-+ "%{m68020:-D__mc68020__ -D__mc68020} " \
-+ "%{mc68020:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-40:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-60:-D__mc68020__ -D__mc68020} " \
-+ "%{m68030:-D__mc68030__ -D__mc68030} " \
-+ "%{m68040:-D__mc68040__ -D__mc68040} " \
-+ "%{m68060:-D__mc68060__ -D__mc68060} " \
-+ "%{noixemul:%(cpp_libnix)} " \
-+ "%{mcrt=nix*:%(cpp_libnix)} " \
-+ "%{mcrt=ixemul:%(cpp_ixemul)} " \
-+ "%{mcrt=clib2:%(cpp_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(cpp_clib2)}}"
-+
-+/* Various -m flags require special flags to the assembler. */
-+
-+#undef ASM_SPEC
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_SPEC \
-+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc} %{!msmall-code:-S}"
-+#else
-+#define ASM_SPEC \
-+ "-gas -esc -ldots -Fhunk -quiet %(asm_cpu) %(asm_cpu_default)
%{msmall-code:-sc}"
-+#endif
-+
-+#undef ASM_CPU_SPEC
-+#define ASM_CPU_SPEC \
-+ "%{mcpu=*:-m%*} " \
-+ "%{m68000|mc68000:-m68010} " \
-+ "%{m6802*|mc68020:-m68020} " \
-+ "%{m68030} " \
-+ "%{m68040} " \
-+ "%{m68060}"
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:%{!mcpu=*:-m68000}}}"
-+#else
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:-m68000}}"
-+#endif
-+
-+/* Choose the right startup file, depending on whether we use base relative
-+ code, base relative code with automatic relocation (-resident), their
-+ 32-bit versions, libnix, profiling or plain crt0.o. */
-+
-+#define STARTFILE_IXEMUL_SPEC \
-+ "%{fbaserel:%{!resident:bcrt0.o%s}}" \
-+ "%{resident:rcrt0.o%s}" \
-+ "%{fbaserel32:%{!resident32:lcrt0.o%s}}" \
-+ "%{resident32:scrt0.o%s}" \
-+ "%{!resident:%{!fbaserel:%{!resident32:%{!fbaserel32:" \
-+ "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}"
-+#define STARTFILE_LIBNIX_SPEC \
-+ "%:sdk_root(libnix/lib/libnix/ " \
-+ "%{ramiga-*:" \
-+ "%{ramiga-lib:libinit.o%s}" \
-+ "%{ramiga-libr:libinitr.o%s}" \
-+ "%{ramiga-dev:devinit.o%s}}" \
-+ "%{!ramiga-*:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:" \
-+ "%{fbaserel32:nlbcrt0.o%s}" \
-+ "%{!fbaserel32:ncrt0.o%s}}}}" \
-+ ")"
-+
-+#define STARTFILE_CLIB2_SPEC \
-+ "%:sdk_root(clib2/lib/ " \
-+ "%{resident32:nr32crt0.o%s}" \
-+ "%{!resident32:" \
-+ "%{fbaserel32:nb32crt0.o%s}" \
-+ "%{!fbaserel32:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:ncrt0.o%s}}}}" \
-+ ")"
-+
-+#undef STARTFILE_SPEC
-+#ifdef TARGET_AMIGAOS_VASM
-+#define STARTFILE_SPEC \
-+ "startup%O%s"
-+#else
-+#define STARTFILE_SPEC \
-+ "%{noixemul:%(startfile_libnix)} " \
-+ "%{mcrt=nix*:%(startfile_libnix)} " \
-+ "%{mcrt=ixemul:%(startfile_ixemul)} " \
-+ "%{mcrt=clib2:%(startfile_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(startfile_clib2)}}"
-+#endif
-+
-+#define ENDFILE_IXEMUL_SPEC ""
-+#define ENDFILE_LIBNIX_SPEC "-lstubs"
-+#define ENDFILE_CLIB2_SPEC ""
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{noixemul:%(endfile_libnix)} " \
-+ "%{mcrt=nix*:%(endfile_libnix)} " \
-+ "%{mcrt=ixemul:%(endfile_ixemul)} " \
-+ "%{mcrt=clib2:%(endfile_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(endfile_clib2)}}"
-+
-+
-+/* Automatically search libamiga.a for AmigaOS specific functions. Note
-+ that we first search the standard C library to resolve as much as
-+ possible from there, since it has names that are duplicated in libamiga.a
-+ which we *don't* want from there. Then search libamiga.a for any calls
-+ that were not generated inline, and finally search the standard C library
-+ again to resolve any references that libamiga.a might have generated.
-+ This may only be a temporary solution since it might be better to simply
-+ remove the things from libamiga.a that should be pulled in from libc.a
-+ instead, which would eliminate the first reference to libc.a. Note that
-+ if we don't search it automatically, it is very easy for the user to try
-+ to put in a -lamiga himself and get it in the wrong place, so that (for
-+ example) calls like sprintf come from -lamiga rather than -lc. */
-+
-+#define LIB_IXEMUL_SPEC \
-+ "%{!p:%{!pg:-lc -lamiga -lc}} " \
-+ "%{p:-lc_p} %{pg:-lc_p}"
-+#define LIB_LIBNIX_SPEC \
-+ "-lnixmain -lnix " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20} " \
-+ "-lamiga " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
-+#define LIB_CLIB2_SPEC \
-+ "-lc -lamiga -ldebug " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LIB_SPEC \
-+ "-lvc -lamiga "
-+#else
-+#define LIB_SPEC \
-+ "%{noixemul:%(lib_libnix)} " \
-+ "%{mcrt=nix*:%(lib_libnix)} " \
-+ "%{mcrt=ixemul:%(lib_ixemul)} " \
-+ "%{mcrt=clib2:%(lib_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(lib_clib2)}}"
-+#endif
-+
-+#define LIBGCC_IXEMUL_SPEC ""
-+#define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20} -lstubs"
-+#define LIBGCC_CLIB2_SPEC "-lc"
-+#define LIBGCC_SPEC "-lgcc " \
-+ "%{noixemul:%(libgcc_libnix)} " \
-+ "%{mcrt=nix*:%(libgcc_libnix)} " \
-+ "%{mcrt=ixemul:%(libgcc_ixemul)} " \
-+ "%{mcrt=clib2:%(libgcc_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(libgcc_clib2)}}"
-+
-+
-+/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-+ compatible debug hunk.
-+ Also, pass appropriate linker flavours depending on user-supplied
-+ commandline options. */
-+
-+#define LINK_IXEMUL_SPEC ""
-+#define LINK_LIBNIX_SPEC "-L%:sdk_root(libnix/lib) -fl libnix"
-+#define LINK_CLIB2_SPEC "-L%:sdk_root(clib2/lib)"
-+
-+/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-+ compatible debug hunk.
-+ Also, pass appropriate linker flavours depending on user-supplied
-+ commandline options. */
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LINK_SPEC \
-+ "%{noixemul:%(link_libnix)} " \
-+ "%{mcrt=nix*:%(link_libnix)} " \
-+ "%{mcrt=ixemul:%(link_ixemul)} " \
-+ "%{mcrt=clib2:%(link_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(link_clib2)}} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl
libnix} %{mcrt=nix*:-fl libnix}} " \
-+ "%{mcpu=68020:-fl libm020} " \
-+ "%{m68020:-fl libm020} " \
-+ "%{mc68020:-fl libm020} " \
-+ "%{m68030:-fl libm020} " \
-+ "%{m68040:-fl libm020} " \
-+ "%{m68060:-fl libm020} " \
-+ "%{m68020-40:-fl libm020} " \
-+ "%{m68020-60:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+#else
-+#define LINK_SPEC \
-+ "%{noixemul:%(link_libnix)} " \
-+ "%{mcrt=nix*:%(link_libnix)} " \
-+ "%{mcrt=ixemul:%(link_ixemul)} " \
-+ "%{mcrt=clib2:%(link_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(link_clib2)}} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl
libnix} %{mcrt=nix*:-fl libnix}} " \
-+ "%{g:-amiga-debug-hunk} " \
-+ "%{mcpu=68020:-fl libm020} " \
-+ "%{mcpu=68030:-fl libm020} " \
-+ "%{mcpu=68040:-fl libm020} " \
-+ "%{mcpu=68060:-fl libm020} " \
-+ "%{m68020:-fl libm020} " \
-+ "%{mc68020:-fl libm020} " \
-+ "%{m68030:-fl libm020} " \
-+ "%{m68040:-fl libm020} " \
-+ "%{m68060:-fl libm020} " \
-+ "%{m68020-40:-fl libm020} " \
-+ "%{m68020-60:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+#endif
-+
-+/* Translate '-resident' to '-fbaserel' (they differ in linking stage
only).
-+ Don't put function addresses in registers for PC-relative code. */
-+
-+#define CC1_SPEC \
-+ "%{resident:-fbaserel} " \
-+ "%{resident32:-fbaserel32} " \
-+ "%{msmall-code:-fno-function-cse}"
-+
-+#define LINK_CPU_SPEC \
-+ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+
-+/* [cahirwpz] A modified copy of LINK_COMMAND_SPEC from gcc/gcc.c file.
-+ Don't prepend libgcc.a to link libraries and make sure the options is
-+ at the end of command line. Otherwise linker chooses generic functions
-+ from libgcc.a instead AmigaOS-specific counterparts from libnix.a. */
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LINK_COMMAND_SPEC \
-+ "%{!fsyntax-only:" \
-+ "%{!c:" \
-+ "%{!M:" \
-+ "%{!MM:" \
-+ "%{!E:" \
-+ "%{!S:" \
-+ "%(linker) -Cvbcc %l %X %{o*} %{A} %{d} %{e*} %{m} " \
-+ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
-+ "%{static:} %{L*} %D %o " \
-+ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
-+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-+ "%{T*} }}}}}} "
-+#else
-+#define LINK_COMMAND_SPEC \
-+ "%{!fsyntax-only:" \
-+ "%{!c:" \
-+ "%{!M:" \
-+ "%{!MM:" \
-+ "%{!E:" \
-+ "%{!S:" \
-+ "%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} " \
-+ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
-+ "%{static:} %{L*} %D %o " \
-+ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
-+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-+ "%{T*} }}}}}} "
-+#endif
-+
-+extern const char * amiga_m68k_prefix_func(int, const char **);
-+
-+#define EXTRA_SPEC_FUNCTIONS \
-+ { "sdk_root", amiga_m68k_prefix_func },
-+
-+/* This macro defines names of additional specifications to put in the specs
-+ that can be used in various specifications like CC1_SPEC. Its definition
-+ is an initializer with a subgrouping for each command option.
-+
-+ Each subgrouping contains a string constant, that defines the
-+ specification name, and a string constant that used by the GCC driver
-+ program.
-+
-+ Do not define this macro if it does not need to do anything. */
-+#undef EXTRA_SPECS
-+#define EXTRA_SPECS \
-+ {"asm_cpu", ASM_CPU_SPEC }, \
-+ {"asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
-+ {"link_cpu", LINK_CPU_SPEC }, \
-+ {"cpp_ixemul", CPP_IXEMUL_SPEC}, \
-+ {"cpp_libnix", CPP_LIBNIX_SPEC}, \
-+ {"cpp_clib2", CPP_CLIB2_SPEC}, \
-+ {"lib_ixemul", LIB_IXEMUL_SPEC}, \
-+ {"lib_libnix", LIB_LIBNIX_SPEC}, \
-+ {"lib_clib2", LIB_CLIB2_SPEC}, \
-+ {"link_ixemul", LINK_IXEMUL_SPEC}, \
-+ {"link_libnix", LINK_LIBNIX_SPEC}, \
-+ {"link_clib2", LINK_CLIB2_SPEC}, \
-+ {"startfile_ixemul", STARTFILE_IXEMUL_SPEC}, \
-+ {"startfile_libnix", STARTFILE_LIBNIX_SPEC}, \
-+ {"startfile_clib2", STARTFILE_CLIB2_SPEC}, \
-+ {"endfile_ixemul", ENDFILE_IXEMUL_SPEC}, \
-+ {"endfile_libnix", ENDFILE_LIBNIX_SPEC}, \
-+ {"endfile_clib2", ENDFILE_CLIB2_SPEC}, \
-+ {"libgcc_ixemul", LIBGCC_IXEMUL_SPEC}, \
-+ {"libgcc_libnix", LIBGCC_LIBNIX_SPEC}, \
-+ {"libgcc_clib2", LIBGCC_CLIB2_SPEC}
-+
-+/* begin-GG-local: dynamic libraries */
-+
-+extern int amigaos_do_collecting (void);
-+extern void amigaos_gccopts_hook (const char *);
-+extern void amigaos_libname_hook (const char* arg);
-+extern void amigaos_collect2_cleanup (void);
-+extern void amigaos_prelink_hook (const char **, int *);
-+extern void amigaos_postlink_hook (const char *);
-+
-+/* This macro is used to check if all collect2 facilities should be used.
-+ We need a few special ones, like stripping after linking. */
-+
-+#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
-+
-+/* This macro is called in collect2 for every GCC argument name.
-+ ARG is a part of commandline (without '\0' at the end). */
-+
-+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
-+
-+/* This macro is called in collect2 for every ld's "-l" or "*.o"
or "*.a"
-+ argument. ARG is a complete argument, with '\0' at the end. */
-+
-+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
-+
-+/* This macro is called at collect2 exit, to clean everything up. */
-+
-+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
-+
-+/* This macro is called just before the first linker invocation.
-+ LD1_ARGV is "char** argv", which will be passed to "ld". STRIP
is an
-+ *address* of "strip_flag" variable. */
-+
-+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
-+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
-+
-+/* This macro is called just after the first linker invocation, in place of
-+ "nm" and "ldd". OUTPUT_FILE is the executable's filename.
*/
-+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
-+
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT)
-+
-+#undef FIXED_INCLUDE_DIR
-+#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../include"
-+
-+// this disables tree_loop_distribute_patterns
-+#define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
-+/* Baserel support. */
-+
-+extern int amiga_is_const_pic_ref(const_rtx x);
-+
-+#undef CONSTANT_ADDRESS_P
-+#define CONSTANT_ADDRESS_P(X) \
-+((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
-+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
-+ || GET_CODE (X) == HIGH \
-+ ))
-+
-+
-+
-+/* Given that symbolic_operand(X), return TRUE if no special
-+ base relative relocation is necessary */
-+
-+#undef LEGITIMATE_PIC_OPERAND_P
-+#define LEGITIMATE_PIC_OPERAND_P(X) ( \
-+ ! symbolic_operand (X, VOIDmode) && \
-+ ! amiga_is_const_pic_ref(X))
-+
-+// (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF ||
GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
-+
-+#undef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".text"
-+
-+#undef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".text"
-+
-+#define EH_TABLES_CAN_BE_READ_ONLY 1
-+
-+
-+/* Max. number of data, address and float registers to be used for passing
-+ integer, pointer and float arguments when TARGET_REGPARM.
-+ It's 4, so d0-d3, a0-a3 and fp0-fp3 can be used. */
-+#undef AMIGAOS_MAX_REGPARM
-+#define AMIGAOS_MAX_REGPARM 4
-+
-+/* The default number of data, address and float registers to use when
-+ user specified '-mregparm' switch, not '-mregparm=<value>'
option. */
-+#undef AMIGAOS_DEFAULT_REGPARM
-+#define AMIGAOS_DEFAULT_REGPARM 2
-+
-+/* 1 if N is a possible register number for function argument passing. */
-+#undef FUNCTION_ARG_REGNO_P
-+#define FUNCTION_ARG_REGNO_P(N) amigaos_function_arg_reg(N)
-+
-+extern int
-+amigaos_function_arg_reg(unsigned regno);
-+
-+//extern bool debug_recog(char const * txt, int which_alternative, int n, rtx *
operands);
-diff --git a/gcc/config/m68k/m68kemb.h b/gcc/config/m68k/m68kemb.h
-index 0d8d88c74ea9..29b3e194f12d 100644
---- gcc/config/m68k/m68kemb.h
-+++ gcc/config/m68k/m68kemb.h
-@@ -32,12 +32,14 @@
- #define NEEDS_UNTYPED_CALL 1
-
- /* Target OS builtins. */
-+#ifndef TARGET_OS_CPP_BUILTINS
- #define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__embedded__"); \
- } \
- while (0)
-+#endif
-
- /* Override the default LIB_SPEC from gcc.c. We don't currently support
- profiling, or libg.a. */
-diff --git a/gcc/config/m68k/math-68881.h b/gcc/config/m68k/math-68881.h
-index 6d9f8b2d4a1f..20a5037cc525 100644
---- gcc/config/m68k/math-68881.h
-+++ gcc/config/m68k/math-68881.h
-@@ -37,7 +37,7 @@
- September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
-
- /* Changed by Ian Lance Taylor:
-- September 1994, use extern inline instead of static inline. */
-+ September 1994, use inline instead of static inline. */
-
- #ifndef __math_68881
- #define __math_68881
-@@ -64,7 +64,7 @@
- })
- #endif
-
--__inline extern double
-+__inline double
- sin (double x)
- {
- double value;
-@@ -75,7 +75,7 @@ sin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cos (double x)
- {
- double value;
-@@ -86,7 +86,7 @@ cos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tan (double x)
- {
- double value;
-@@ -97,7 +97,7 @@ tan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- asin (double x)
- {
- double value;
-@@ -108,7 +108,7 @@ asin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- acos (double x)
- {
- double value;
-@@ -119,7 +119,7 @@ acos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan (double x)
- {
- double value;
-@@ -130,7 +130,7 @@ atan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan2 (double y, double x)
- {
- double pi, pi_over_2;
-@@ -187,7 +187,7 @@ atan2 (double y, double x)
- }
- }
-
--__inline extern double
-+__inline double
- sinh (double x)
- {
- double value;
-@@ -198,7 +198,7 @@ sinh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cosh (double x)
- {
- double value;
-@@ -209,7 +209,7 @@ cosh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tanh (double x)
- {
- double value;
-@@ -220,7 +220,7 @@ tanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atanh (double x)
- {
- double value;
-@@ -231,7 +231,7 @@ atanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- exp (double x)
- {
- double value;
-@@ -242,7 +242,7 @@ exp (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- expm1 (double x)
- {
- double value;
-@@ -253,7 +253,7 @@ expm1 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log (double x)
- {
- double value;
-@@ -264,7 +264,7 @@ log (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log1p (double x)
- {
- double value;
-@@ -275,7 +275,7 @@ log1p (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log10 (double x)
- {
- double value;
-@@ -286,7 +286,7 @@ log10 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- sqrt (double x)
- {
- double value;
-@@ -297,13 +297,13 @@ sqrt (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- hypot (double x, double y)
- {
- return sqrt (x*x + y*y);
- }
-
--__inline extern double
-+__inline double
- pow (double x, double y)
- {
- if (x > 0)
-@@ -352,7 +352,7 @@ pow (double x, double y)
- }
- }
-
--__inline extern double
-+__inline double
- fabs (double x)
- {
- double value;
-@@ -363,7 +363,7 @@ fabs (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- ceil (double x)
- {
- int rounding_mode, round_up;
-@@ -385,7 +385,7 @@ ceil (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- floor (double x)
- {
- int rounding_mode, round_down;
-@@ -408,7 +408,7 @@ floor (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- rint (double x)
- {
- int rounding_mode, round_nearest;
-@@ -430,7 +430,7 @@ rint (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- fmod (double x, double y)
- {
- double value;
-@@ -442,7 +442,7 @@ fmod (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- drem (double x, double y)
- {
- double value;
-@@ -454,7 +454,7 @@ drem (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- scalb (double x, int n)
- {
- double value;
-@@ -466,7 +466,7 @@ scalb (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- logb (double x)
- {
- double exponent;
-@@ -477,7 +477,7 @@ logb (double x)
- return exponent;
- }
-
--__inline extern double
-+__inline double
- ldexp (double x, int n)
- {
- double value;
-@@ -489,7 +489,7 @@ ldexp (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- frexp (double x, int *exp)
- {
- double float_exponent;
-@@ -514,7 +514,7 @@ frexp (double x, int *exp)
- return mantissa;
- }
-
--__inline extern double
-+__inline double
- modf (double x, double *ip)
- {
- double temp;
-diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
-index 186436c42b77..9533e65ceaab 100644
---- gcc/config/m68k/predicates.md
-+++ gcc/config/m68k/predicates.md
-@@ -30,6 +30,10 @@
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
-+#ifdef TARGET_AMIGA
-+ if (flag_pic >= 3 && amiga_is_const_pic_ref(op))
-+ return 0;
-+#endif
- return general_operand (op, mode);
- })
-
-diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos
-new file mode 100755
-index 000000000000..bf9c5279d04f
---- /dev/null
-+++ gcc/config/m68k/t-amigaos
-@@ -0,0 +1,28 @@
-+# Makefile fragment for AmigaOS target.
-+
-+# Extra object file linked to the cc1* executables.
-+amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H)
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+# Additional target dependent options for compiling libgcc.a. This just
-+# ensures that we don't compile libgcc* with anything other than a
-+# fixed stack.
-+
-+#TARGET_LIBGCC2_CFLAGS = -mfixedstack
-+
-+### begin-GG-local: dynamic libraries
-+# Extra objects that get compiled and linked to collect2
-+
-+EXTRA_COLLECT2_OBJS = amigacollect2.o
-+
-+# Build supplimentary AmigaOS target support file for collect2
-+amigacollect2.o: amigacollect2.c
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+ -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION)
-+### end-GG-local
-+
-+# Support for building multiple version of libgcc, libquadmath, libobjc and
libstdc++-v3
-+MULTILIB_OPTIONS = m68020 fbaserel/fbaserel32
-+MULTILIB_DIRNAMES = libm020 libb libb32
-+MULTILIB_EXTRA_OPTS = noixemul
-+MULTILIB_EXCEPTIONS = fbaserel32
-\ No newline at end of file
-diff --git a/gcc/config/m68k/x-amigaos b/gcc/config/m68k/x-amigaos
-new file mode 100755
-index 000000000000..a8f60b80f9f4
---- /dev/null
-+++ gcc/config/m68k/x-amigaos
-@@ -0,0 +1,104 @@
-+# Makefile fragment for AmigaOS host
-+
-+# Each compilation environment (Manx, Dice, GCC, SAS/C, etc) provides its
-+# own equivalent of the UNIX /usr/include tree. For gcc, the standard headers
-+# are in /gg/include and system specific headers are in /gg/os-include.
-+# Use these paths for fixincludes.
-+
-+SYSTEM_HEADER_DIR = $(prefix)/include
-+
-+# Uncomment the following macro to get a resident GCC. We don't do it
-+# by default, since we want to support users with mc68000.
-+# WARNING! If you uncomment this, you MUST add the same flags to the
-+# libiberty's Makefile (libiberty is now linked into GCC executables).
-+
-+#RESIDENT = -m68020 -resident32
-+
-+# Additional host flags that are not used when compiling with GCC_FOR_TARGET,
-+# such as when compiling the libgcc* runtime archives. GCC uses stack
-+# a lot, and since AmigaOS provides processes with a small, fixed size
-+# stack, we have to generate code that will extend it whenever necessary.
-+
-+XCFLAGS = -mstackextend $(RESIDENT)
-+
-+# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are
-+# build with a custom "makeinfo".
-+
-+# Arrange for guides to be build with GCC, in the build directory.
-+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_DOC_TARGETS = guide gcc-amigaos-doc
-+### end-GG-local
-+
-+# Actually build guides
-+
-+guide:: doc/cpp.guide doc/gcc.guide doc/gccint.guide \
-+ doc/gccinstall.guide doc/cppinternals.guide
-+
-+doc/cpp.guide: $(TEXI_CPP_FILES)
-+doc/gcc.guide: $(TEXI_GCC_FILES)
-+doc/gccint.guide: $(TEXI_GCCINT_FILES)
-+doc/cppinternals.guide: $(TEXI_CPPINT_FILES)
-+
-+doc/%.guide: %.texi
-+ if [ x$(BUILD_INFO) = xinfo ]; then \
-+ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
-+ -I $(docdir)/include -o $@ $<; \
-+ fi
-+
-+# Duplicate entry to handle renaming of gccinstall.guide
-+doc/gccinstall.guide: $(TEXI_GCCINSTALL_FILES)
-+ if [ x$(BUILD_INFO) = xinfo ]; then \
-+ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
-+ -I $(docdir)/include -o $@ install.texi; \
-+ fi
-+
-+# Arrange for guides to be installed with GCC.
-+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc
-+### end-GG-local
-+
-+# Where the guide files go
-+
-+guidedir = $(prefix)/guide
-+
-+# Actually install guides.
-+
-+installdirs-guide:
-+ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir)
-+
-+install-guide: doc installdirs-guide \
-+ $(DESTDIR)$(guidedir)/cpp.guide \
-+ $(DESTDIR)$(guidedir)/gcc.guide \
-+ $(DESTDIR)$(guidedir)/cppinternals.guide \
-+ $(DESTDIR)$(guidedir)/gccinstall.guide \
-+ $(DESTDIR)$(guidedir)/gccint.guide
-+
-+$(DESTDIR)$(guidedir)/%.guide: doc/%.guide installdirs-guide
-+ rm -f $@
-+ if [ -f $< ]; then \
-+ for f in $(<)*; do \
-+ realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
-+ $(INSTALL_DATA) $$f $(DESTDIR)$(guidedir)/$$realfile; \
-+ chmod a-x $(DESTDIR)$(guidedir)/$$realfile; \
-+ done; \
-+ else true; fi
-+
-+### begin-GG-local: gcc-amigaos
-+# Build and install gcc-amigaos.guide - documentation specific to the
-+# AmigaOS port of GCC.
-+
-+gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide
-+
-+doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi
-+
-+install-gcc-amigaos-doc: doc installdirs installdirs-guide \
-+ $(DESTDIR)$(infodir)/gcc-amigaos.info \
-+ $(DESTDIR)$(guidedir)/gcc-amigaos.guide
-+### end-GG-local
-+
-+host-amigaos.o : $(srcdir)/config/m68k/host-amigaos.c $(CONFIG_H) $(SYSTEM_H) \
-+ coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
-+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+ $(srcdir)/config/m68k/host-amigaos.c
-diff --git a/gcc/config/m68k/xm-amigaos.h b/gcc/config/m68k/xm-amigaos.h
-new file mode 100755
-index 000000000000..bb571ba040b3
---- /dev/null
-+++ gcc/config/m68k/xm-amigaos.h
-@@ -0,0 +1,64 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#ifndef _FCNTL_H_
-+#include <fcntl.h>
-+#endif
-+
-+/* AmigaOS specific headers, such as from the Native Developer Update kits,
-+ go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of
-+ Unix "/usr/include". All other include paths are set in Makefile. */
-+
-+#define SYSTEM_INCLUDE_DIR "/gg/os-include"
-+#define STANDARD_INCLUDE_DIR "/gg/include"
-+
-+#define STANDARD_EXEC_PREFIX_1 "/gg/libexec/gcc/"
-+#define STANDARD_EXEC_PREFIX_2 "/gg/lib/gcc/"
-+#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/"
-+#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/"
-+
-+/* The AmigaOS stores file names with regard to upper/lower case, but actions
-+ on existing files are case independent on the standard filesystems.
-+
-+ A good example of where this causes problems is the conflict between the C
-+ include file <string.h> and the C++ include file <String.h>, where the
C++
-+ include file dir is searched first and thus causes includes of <string.h>
-+ to include <String.h> instead.
-+
-+ In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as
-+ the name of the function that takes the same args as open() and does case
-+ dependent opens. */
-+
-+#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE))
-+
-+/* On the AmigaOS, there are two pathname separators, '/' (DIR_SEPARATOR)
-+ and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct
-+ character, so we don't have to explicitly set it. */
-+
-+#define DIR_SEPARATOR '/'
-+#define VOL_SEPARATOR ':'
-+#define DIR_SEPARATOR_2 VOL_SEPARATOR
-+
-+/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as
-+ STANDARD_INCLUDE_DIR. */
-+
-+#undef PREFIX_INCLUDE_DIR
-diff --git a/gcc/coretypes.h b/gcc/coretypes.h
-index 12067fdf5348..f0f069f6afa2 100644
---- gcc/coretypes.h
-+++ gcc/coretypes.h
-@@ -52,9 +52,9 @@ typedef const struct bitmap_head *const_bitmap;
- struct simple_bitmap_def;
- typedef struct simple_bitmap_def *sbitmap;
- typedef const struct simple_bitmap_def *const_sbitmap;
--struct rtx_def;
--typedef struct rtx_def *rtx;
--typedef const struct rtx_def *const_rtx;
-+class rtx_def;
-+typedef class rtx_def *rtx;
-+typedef const class rtx_def *const_rtx;
-
- /* Subclasses of rtx_def, using indentation to show the class
- hierarchy, along with the relevant invariant.
-diff --git a/gcc/df-scan.c b/gcc/df-scan.c
-index 98de84405428..1f23452afe19 100644
---- gcc/df-scan.c
-+++ gcc/df-scan.c
-@@ -1807,6 +1807,12 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
- df_ref *ref_ptr;
- struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
-
-+ if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE))
-+ {
-+ --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
-+ ++df->hard_regs_live_count[new_regno];
-+ }
-+
- DF_REF_REGNO (the_ref) = new_regno;
- DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
-
-diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
-index f241073866b4..566aaaf4e370 100644
---- gcc/dwarf2out.c
-+++ gcc/dwarf2out.c
-@@ -451,7 +451,7 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- /*global=*/1);
- lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,
- /*global=*/0);
-- flags = ((! flag_pic
-+ flags = (( (!flag_pic || flag_pic > 2)
- || ((fde_encoding & 0x70) != DW_EH_PE_absptr
- && (fde_encoding & 0x70) != DW_EH_PE_aligned
- && (per_encoding & 0x70) != DW_EH_PE_absptr
-@@ -469,6 +469,16 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- eh_frame_section = ((flags == SECTION_WRITE)
- ? data_section : readonly_data_section);
- #endif /* EH_FRAME_SECTION_NAME */
-+
-+#ifdef TARGET_AMIGA
-+ switch_to_section (data_section);
-+ fputs("\t__EH_FRAME_OBJECT__:\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long
0\n\t.long 0\n\t.long 0\n", asm_out_file);
-+ fputs("\t.stabs
\"__EH_FRAME_OBJECTS__\",24,0,0,__EH_FRAME_OBJECT__\n", asm_out_file);
-+
-+ switch_to_section (eh_frame_section);
-+ ASM_OUTPUT_LABEL (asm_out_file, "_EH_FRAME_BEGIN__");
-+ fputs("\t.stabs
\"__EH_FRAME_BEGINS__\",22,0,0,__EH_FRAME_BEGIN__\n", asm_out_file);
-+#endif
- }
-
- switch_to_section (eh_frame_section);
-diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
-index 0fcd9d95e5b4..b2a18e7e4188 100644
---- gcc/emit-rtl.c
-+++ gcc/emit-rtl.c
-@@ -2123,7 +2123,11 @@ change_address_1 (rtx memref, machine_mode mode, rtx addr, int
validate,
- if (validate && !lra_in_progress)
- {
- if (reload_in_progress || reload_completed)
-- gcc_assert (memory_address_addr_space_p (mode, addr, as));
-+ {
-+ bool r = memory_address_addr_space_p (mode, addr, as);
-+ if (!r) debug_rtx(addr);
-+ gcc_assert (r);
-+ }
- else
- addr = memory_address_addr_space (mode, addr, as);
- }
-diff --git a/gcc/except.c b/gcc/except.c
-index 2a1073f80cc4..194478f8454c 100644
---- gcc/except.c
-+++ gcc/except.c
-@@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
- #include "cfgloop.h"
- #include "builtins.h"
- #include "tree-hash-traits.h"
-+#include "target-def.h"
-
- static GTY(()) int call_site_base;
-
-@@ -2850,14 +2851,14 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
- it linkonce if we have COMDAT groups to tie them together. */
- if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
- flags |= SECTION_LINKONCE;
-- sprintf (section_name, ".gcc_except_table.%s", fnname);
-+ sprintf (section_name, TARGET_GCC_EXCEPT_TABLE_S, fnname);
- s = get_section (section_name, flags, current_function_decl);
- free (section_name);
- }
- else
- #endif
- exception_section
-- = s = get_section (".gcc_except_table", flags, NULL);
-+ = s = get_section (TARGET_GCC_EXCEPT_TABLE, flags, NULL);
- }
- else
- exception_section
-diff --git a/gcc/final.c b/gcc/final.c
-index 55cf509611f7..fa8b2964a40d 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2151,6 +2151,7 @@ call_from_call_insn (rtx_call_insn *insn)
- SEEN is used to track the end of the prologue, for emitting
- debug information. We force the emission of a line note after
- both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */
-+rtx_insn * current_insn;
-
- rtx_insn *
- final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
-@@ -2160,6 +2161,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p
ATTRIBUTE_UNUSED,
- rtx set;
- #endif
- rtx_insn *next;
-+ current_insn = insn;
-
- insn_counter++;
-
-@@ -3622,6 +3624,12 @@ do_assembler_dialects (const char *p, int *dialect)
- void
- output_asm_insn (const char *templ, rtx *operands)
- {
-+ extern bool be_very_verbose;
-+ extern void append_reg_usage(FILE *, rtx_insn *);
-+
-+ extern bool dump_reg_track;
-+ void append_reg_cache (FILE * f, rtx_insn * insn);
-+
- const char *p;
- int c;
- #ifdef ASSEMBLER_DIALECT
-@@ -3778,6 +3786,11 @@ output_asm_insn (const char *templ, rtx *operands)
- putc (c, asm_out_file);
- }
-
-+ if (be_very_verbose)
-+ append_reg_usage(asm_out_file, current_insn);
-+ if (dump_reg_track)
-+ append_reg_cache(asm_out_file, current_insn);
-+
- /* Write out the variable names for operands, if we know them. */
- if (flag_verbose_asm)
- output_asm_operand_names (operands, oporder, ops);
-@@ -3995,6 +4008,7 @@ output_addr_const (FILE *file, rtx x)
- if (targetm.asm_out.output_addr_const_extra (file, x))
- break;
-
-+ debug_rtx(current_output_insn);
- output_operand_lossage ("invalid expression as operand");
- }
- }
-diff --git a/gcc/function.c b/gcc/function.c
-index 6942a504127f..ebe3e1c37121 100644
---- gcc/function.c
-+++ gcc/function.c
-@@ -39,9 +39,9 @@ along with GCC; see the file COPYING3. If not see
- #include "rtl.h"
- #include "tree.h"
- #include "gimple-expr.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "df.h"
--#include "tm_p.h"
- #include "stringpool.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/gcc.c b/gcc/gcc.c
-index 85ea19bd3a09..a4da7d515ce5 100644
---- gcc/gcc.c
-+++ gcc/gcc.c
-@@ -10107,3 +10107,40 @@ driver_get_configure_time_options (void (*cb) (const char
*option,
- obstack_free (&obstack, NULL);
- n_switches = 0;
- }
-+
-+#ifdef TARGET_AMIGA
-+const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
-+ char * p = 0;
-+ if (standard_libexec_prefix)
-+ {
-+ char * glp = concat(standard_libexec_prefix, "", NULL);
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ p[1] = 0;
-+ p = concat(glp, "m68k-unknown-amigaos/", NULL);
-+ }
-+ }
-+ }
-+ free(glp);
-+ }
-+ if (!p)
-+ p = concat("../../../../", "", NULL);
-+
-+ for (int i = 0; i < argc; ++i) {
-+ char * q = concat(p, argv[i], NULL);
-+ free(p);
-+ p = q;
-+ }
-+// printf("amiga_m68k_prefix_func='%s'\n", p);
-+ return p;
-+}
-+#endif
-diff --git a/gcc/gcse.c b/gcc/gcse.c
-index 5b2c96ecb5a6..f74e733f9337 100644
---- gcc/gcse.c
-+++ gcc/gcse.c
-@@ -4075,7 +4075,9 @@ pass_rtl_pre::gate (function *fun)
- {
- return optimize > 0 && flag_gcse
- && !fun->calls_setjmp
-+#ifndef TARGET_AMIGA
- && optimize_function_for_speed_p (fun)
-+#endif
- && dbg_cnt (pre);
- }
-
-@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass
- bool
- pass_rtl_hoist::gate (function *)
- {
-+#ifdef TARGET_AMIGA
-+ return false;
-+#else
- return optimize > 0 && flag_gcse
- && !cfun->calls_setjmp
- /* It does not make sense to run code hoisting unless we are optimizing
-@@ -4125,6 +4130,7 @@ pass_rtl_hoist::gate (function *)
- bigger if we did PRE (when optimizing for space, we don't run PRE). */
- && optimize_function_for_size_p (cfun)
- && dbg_cnt (hoist);
-+#endif
- }
-
- } // anon namespace
-diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
-index d711530d0535..4f08f81a3ae0 100644
---- gcc/ginclude/stddef.h
-+++ gcc/ginclude/stddef.h
-@@ -325,6 +325,7 @@ typedef __rune_t rune_t;
- #define __WCHAR_TYPE__ int
- #endif
- #ifndef __cplusplus
-+#define _WCHAR_T_ int
- typedef __WCHAR_TYPE__ wchar_t;
- #endif
- #endif
-diff --git a/gcc/hwint.h b/gcc/hwint.h
-index 4dd255d486c5..d5296a81d08e 100644
---- gcc/hwint.h
-+++ gcc/hwint.h
-@@ -295,7 +295,7 @@ abs_hwi (HOST_WIDE_INT x)
- inline unsigned HOST_WIDE_INT
- absu_hwi (HOST_WIDE_INT x)
- {
-- return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
-+ return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(signed HOST_WIDE_INT)x;
- }
-
- #endif /* ! GCC_HWINT_H */
-diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
-index 86c48f14f64d..dc72a5f21021 100644
---- gcc/ipa-chkp.c
-+++ gcc/ipa-chkp.c
-@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
-+#include "target.h"
- #include "tree.h"
- #include "gimple.h"
- #include "tree-pass.h"
-diff --git a/gcc/opts.c b/gcc/opts.c
-index 8f9862db57c2..6a87349e6a70 100644
---- gcc/opts.c
-+++ gcc/opts.c
-@@ -530,8 +530,10 @@ static const struct default_options default_options_table[] =
- { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
-+#ifndef TARGET_AMIGA
- { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
-+#endif
- { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
- { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
-diff --git a/gcc/passes.c b/gcc/passes.c
-index e89618111245..1d53bb23b1b0 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2269,6 +2269,29 @@ override_gate_status (opt_pass *pass, tree func, bool
gate_status)
- }
-
-
-+void dump_insns(char const * name)
-+{
-+ rtx_insn *insn, *next;
-+ fprintf(stderr, "====================================\npass: %s\n", name);
-+ for (insn = get_insns(); insn; insn = next)
-+ {
-+ next = NEXT_INSN(insn);
-+ debug_rtx(insn);
-+#if 0
-+ if (NONJUMP_INSN_P (insn))
-+ {
-+ rtx set= single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ if (amiga_is_const_pic_ref(SET_SRC(set)) && MEM_P(SET_DEST(set)))
-+ debug_rtx(insn);
-+ }
-+#endif
-+ }
-+}
-+
-+
- /* Execute PASS. */
-
- bool
-@@ -2278,6 +2301,9 @@ execute_one_pass (opt_pass *pass)
-
- bool gate_status;
-
-+ if (string_bbb_opts && strchr (string_bbb_opts, 'Y'))
-+ dump_insns(pass->name);
-+
- /* IPA passes are executed on whole program, so cfun should be NULL.
- Other passes need function context set. */
- if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 7db9c9577cf4..61d0e4d47377 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -386,6 +386,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_gen_hsail);
-
- NEXT_PASS (pass_expand);
-+ NEXT_PASS (pass_bbb_baserel);
-
- NEXT_PASS (pass_rest_of_compilation);
- PUSH_INSERT_PASSES_WITHIN (pass_rest_of_compilation)
-@@ -458,6 +459,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_cprop_hardreg);
- NEXT_PASS (pass_fast_rtl_dce);
- NEXT_PASS (pass_reorder_blocks);
-+ NEXT_PASS (pass_bbb_optimizations);
- NEXT_PASS (pass_branch_target_load_optimize2);
- NEXT_PASS (pass_leaf_regs);
- NEXT_PASS (pass_split_before_sched2);
-diff --git a/gcc/recog.c b/gcc/recog.c
-index 92b2aa31a777..73d1fd1b1336 100644
---- gcc/recog.c
-+++ gcc/recog.c
-@@ -3252,6 +3252,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len,
rtx_insn *attempt)
- /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
- match more than one insn, or to be split into more than one insn. */
- old_insn = peep2_insn_data[peep2_current].insn;
-+
- if (RTX_FRAME_RELATED_P (old_insn))
- {
- bool any_note = false;
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-old mode 100644
-new mode 100755
-index 9643f328ea3e..1ed6557ee713
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -374,44 +374,45 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- = (enum reg_class) targetm.preferred_rename_class (super_class);
-
- /* Pick and check the register from the tied chain iff the tied chain
-- is not renamed. */
-+ is not renamed. */
- if (this_head->tied_chain && !this_head->tied_chain->renamed
- && check_new_reg_p (old_reg, this_head->tied_chain->regno,
- this_head, *unavailable))
- return this_head->tied_chain->regno;
-
- /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
-- over registers that belong to PREFERRED_CLASS and try to find the
-- best register within the class. If that failed, we iterate in
-- the second pass over registers that don't belong to the class.
-- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-- ascending order without any preference. */
-+ over registers that belong to PREFERRED_CLASS and try to find the
-+ best register within the class. If that failed, we iterate in
-+ the second pass over registers that don't belong to the class.
-+ If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-+ ascending order without any preference. */
- has_preferred_class = (preferred_class != NO_REGS);
- for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
- {
- int new_reg;
-- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
-- {
-- if (has_preferred_class
-+ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
-+ {
-+ if (has_preferred_class
- && (pass == 0)
- != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
-- new_reg))
-- continue;
-+ new_reg))
-+ continue;
-
-- if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-- continue;
-+ if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-+ continue;
-
-- if (!best_rename)
-- return new_reg;
-+ if (!best_rename)
-+ return new_reg;
-
-- /* In the first pass, we force the renaming of registers that
-- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago. */
-- if ((pass == 0
-+ /* In the first pass, we force the renaming of registers that
-+ don't belong to PREFERRED_CLASS to registers that do, even
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if (((pass == 0 || !has_preferred_class)
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-- best_new_reg = new_reg;
-+ best_new_reg = new_reg;
- }
- if (pass == 0 && best_new_reg != old_reg)
- break;
-@@ -897,7 +898,7 @@ regrename_analyze (bitmap bb_mask)
- if (!range_overlaps_hard_reg_set_p (live, chain->regno,
- chain->nregs))
- continue;
--
-+
- n_succs_used++;
-
- dest_ri = (struct bb_rename_info *)e->dest->aux;
-@@ -921,7 +922,7 @@ regrename_analyze (bitmap bb_mask)
- printed = true;
- fprintf (dump_file,
- " merging chains %d (->%d) and %d (->%d) [%s]\n",
-- k, incoming_chain->id, j, chain->id,
-+ k, incoming_chain->id, j, chain->id,
- reg_names[incoming_chain->regno]);
- }
-
-@@ -954,7 +955,7 @@ regrename_analyze (bitmap bb_mask)
- numbering in its subpatterns. */
-
- bool
--regrename_do_replace (struct du_head *head, int reg)
-+regrename_do_replace (struct du_head *head, int regno)
- {
- struct du_chain *chain;
- unsigned int base_regno = head->regno;
-@@ -962,19 +963,20 @@ regrename_do_replace (struct du_head *head, int reg)
-
- for (chain = head->first; chain; chain = chain->next_use)
- {
-- unsigned int regno = ORIGINAL_REGNO (*chain->loc);
-- struct reg_attrs *attr = REG_ATTRS (*chain->loc);
-- int reg_ptr = REG_POINTER (*chain->loc);
-+ unsigned int orig_regno = ORIGINAL_REGNO(*chain->loc);
-+ struct reg_attrs *attr = REG_ATTRS(*chain->loc);
-+ int reg_ptr = REG_POINTER(*chain->loc);
-
- if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) !=
base_regno)
-- validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
-- gen_rtx_UNKNOWN_VAR_LOC (), true);
-+ validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC(chain->insn)),
-+ gen_rtx_UNKNOWN_VAR_LOC (),
-+ true);
- else
- {
-- validate_change (chain->insn, chain->loc,
-- gen_raw_REG (GET_MODE (*chain->loc), reg), true);
-- if (regno >= FIRST_PSEUDO_REGISTER)
-- ORIGINAL_REGNO (*chain->loc) = regno;
-+ validate_change (chain->insn, chain->loc,
-+ gen_raw_REG (GET_MODE(*chain->loc), regno), true);
-+ if (orig_regno >= FIRST_PSEUDO_REGISTER)
-+ ORIGINAL_REGNO (*chain->loc) = orig_regno;
- REG_ATTRS (*chain->loc) = attr;
- REG_POINTER (*chain->loc) = reg_ptr;
- }
-@@ -983,10 +985,29 @@ regrename_do_replace (struct du_head *head, int reg)
- if (!apply_change_group ())
- return false;
-
-- mode = GET_MODE (*head->first->loc);
-+ mode = GET_MODE(*head->first->loc);
- head->renamed = 1;
-- head->regno = reg;
-- head->nregs = hard_regno_nregs[reg][mode];
-+ head->regno = regno;
-+ head->nregs = hard_regno_nregs[regno][mode];
-+
-+ /* SBF: also update the current df info, move from base_regno -> regno. */
-+ if (base_regno < FIRST_PSEUDO_REGISTER && regno <
FIRST_PSEUDO_REGISTER)
-+ for (chain = head->first; chain; chain = chain->next_use)
-+ {
-+ if (DEBUG_INSN_P (chain->insn) &&
VAR_LOC_UNKNOWN_P(INSN_VAR_LOCATION_LOC(chain->insn)))
-+ continue;
-+ /* undo regno patch - will be patched again */
-+ if (REGNO (*chain->loc) == regno)
-+ SET_REGNO(*chain->loc, base_regno);
-+ df_ref_change_reg_with_loc (*chain->loc, regno);
-+
-+ SET_REGNO(*chain->loc, regno);
-+ }
-+
-+ /* Mark the old regno as no longer used. */
-+ if (!df->hard_regs_live_count[base_regno])
-+ df_set_regs_ever_live (base_regno, false);
-+
- return true;
- }
-
-@@ -1912,7 +1933,6 @@ const pass_data pass_data_regrename =
- 0, /* todo_flags_start */
- TODO_df_finish, /* todo_flags_finish */
- };
--
- class pass_regrename : public rtl_opt_pass
- {
- public:
-@@ -1923,7 +1943,7 @@ class pass_regrename : public rtl_opt_pass
- /* opt_pass methods: */
- virtual bool gate (function *)
- {
-- return (optimize > 0 && (flag_rename_registers));
-+ return (optimize > 0 && (flag_rename_registers) &&
!TARGET_AMIGA);
- }
-
- virtual unsigned int execute (function *) { return regrename_optimize (); }
-diff --git a/gcc/target-def.h b/gcc/target-def.h
-index ec5e09e568e6..9fbfde121095 100644
---- gcc/target-def.h
-+++ gcc/target-def.h
-@@ -108,3 +108,11 @@
- #include "hooks.h"
- #include "targhooks.h"
- #include "insn-target-def.h"
-+
-+#ifndef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table"
-+#endif
-+
-+#ifndef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".gcc_except_table.%s"
-+#endif
-diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
-index 28dac22add66..16aa71ca4ee4 100644
---- gcc/tree-chkp.c
-+++ gcc/tree-chkp.c
-@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
-index 5f5055d3a6c1..76c0996850f4 100644
---- gcc/tree-pass.h
-+++ gcc/tree-pass.h
-@@ -590,6 +590,8 @@ extern rtl_opt_pass *make_pass_branch_target_load_optimize2
(gcc::context
- *ctxt);
- extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_optimizations (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_baserel (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
-diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
-index 9f09d30b1f91..ab9c0117b078 100644
---- gcc/var-tracking.c
-+++ gcc/var-tracking.c
-@@ -92,10 +92,10 @@
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "alloc-pool.h"
- #include "tree-pass.h"
--#include "tm_p.h"
- #include "insn-config.h"
- #include "regs.h"
- #include "emit-rtl.h"
-diff --git a/gcc/varasm.c b/gcc/varasm.c
-index b65f29c13a46..8ead5ec3fcbb 100644
---- gcc/varasm.c
-+++ gcc/varasm.c
-@@ -252,7 +252,6 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void
*),
- sect->unnamed.callback = callback;
- sect->unnamed.data = data;
- sect->unnamed.next = unnamed_sections;
--
- unnamed_sections = sect;
- return sect;
- }
-@@ -2228,11 +2227,17 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
- else
- {
- /* Special-case handling of vtv comdat sections. */
-- if (sect->named.name
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED &&
sect->named.name
- && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
- handle_vtv_comdat_section (sect, decl);
- else
-- switch_to_section (sect);
-+ {
-+#ifdef TARGET_AMIGA
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED)
-+ sect->named.decl = decl;
-+#endif
-+ switch_to_section (sect);
-+ }
- if (align > BITS_PER_UNIT)
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- assemble_variable_contents (decl, name, dont_output_data);
-@@ -4962,7 +4967,7 @@ output_constructor_regular_field (oc_local_state *local)
- if each element has the proper size. */
- if (local->field != NULL_TREE || local->index != NULL_TREE)
- {
-- if (fieldpos > local->total_bytes)
-+ if (fieldpos >= local->total_bytes)
- {
- assemble_zeros (fieldpos - local->total_bytes);
- local->total_bytes = fieldpos;
-diff --git a/libcpp/lex.c b/libcpp/lex.c
-index e5a0397f3099..c2131adeb38e 100644
---- libcpp/lex.c
-+++ libcpp/lex.c
-@@ -64,6 +64,10 @@ static tokenrun *next_tokenrun (tokenrun *);
-
- static _cpp_buff *new_buff (size_t);
-
-+/*
-+ * SBF: This flag is set if an asm statement is parsed, to support multiline strings in
__asm()
-+ */
-+int in_assembler_directive;
-
- /* Utility routine:
-
-@@ -1063,7 +1067,10 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
- else if (note->type == 0)
- /* Already processed in lex_raw_string. */;
- else
-- abort ();
-+ {
-+// abort ();
-+ printf("ups: note type=%d\n", note->type);
-+ }
- }
- }
-
-@@ -1875,6 +1882,20 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar
*base)
- break;
- else if (c == '\n')
- {
-+ /*
-+ * SBF: allow multi-line strings
-+ * Ignore the line end and move to next line.
-+ * Only fail, if there is no next line
-+ */
-+ if (in_assembler_directive)
-+ {
-+ cpp_buffer *buffer = pfile->buffer;
-+ if (buffer->cur < buffer->rlimit)
-+ CPP_INCREMENT_LINE (pfile, 0);
-+ buffer->need_line = true;
-+ if (_cpp_get_fresh_line (pfile))
-+ continue;
-+ }
- cur--;
- /* Unmatched quotes always yield undefined behavior, but
- greedy lexing means that what appears to be an unterminated
-diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
-index f09b39b0e85f..39f91d1567b6 100644
---- libgcc/Makefile.in
-+++ libgcc/Makefile.in
-@@ -230,7 +230,7 @@ endif
- # Options to use when compiling libgcc2.a.
- #
- LIBGCC2_DEBUG_CFLAGS = -g
--LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
-+LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
- $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
- -fbuilding-libgcc -fno-stack-protector \
- $(INHIBIT_LIBC_CFLAGS)
-@@ -284,7 +284,7 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CFLAGS) $(HOST_LIBGCC2_CFLAGS)
\
- $(INCLUDES) @set_have_cc_tls@ @set_use_emutls@
-
- # Options to use when compiling crtbegin/end.
--CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
-+CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
- $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
- -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
- -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 6f6810cf0baf..7117e7983b53 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -816,6 +816,11 @@ m32r-*-linux*)
- m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
-+m68k-*-amiga*)
-+ tmake_file="$tmake_file m68k/t-glue m68k/t-floatlib soft-fp"
-+ CFLAGS="-Os"
-+# tmake_file="$tmake_file m68k/t-glue soft-fp"
-+ ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
- ;;
-diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
-index fe41edf26aa0..90926104d8fd 100644
---- libgcc/config/m68k/fpgnulib.c
-+++ libgcc/config/m68k/fpgnulib.c
-@@ -105,6 +105,7 @@ union long_double_long
-
- #ifndef EXTFLOAT
-
-+#ifdef __UNORDSF2
- int
- __unordsf2(float a, float b)
- {
-@@ -118,7 +119,9 @@ __unordsf2(float a, float b)
- return 1;
- return 0;
- }
-+#endif
-
-+#ifdef __UNORDDF2
- int
- __unorddf2(double a, double b)
- {
-@@ -134,7 +137,9 @@ __unorddf2(double a, double b)
- return 1;
- return 0;
- }
-+#endif
-
-+#ifdef __FLOATUNSIDF
- /* convert unsigned int to double */
- double
- __floatunsidf (unsigned long a1)
-@@ -167,7 +172,9 @@ __floatunsidf (unsigned long a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __FLOATSIDF
- /* convert int to double */
- double
- __floatsidf (long a1)
-@@ -213,7 +220,9 @@ __floatsidf (long a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __FLOATUNSISF
- /* convert unsigned int to float */
- float
- __floatunsisf (unsigned long l)
-@@ -221,7 +230,10 @@ __floatunsisf (unsigned long l)
- double foo = __floatunsidf (l);
- return foo;
- }
-+#endif
-
-+
-+#ifdef __FLOATSISF
- /* convert int to float */
- float
- __floatsisf (long l)
-@@ -229,7 +241,10 @@ __floatsisf (long l)
- double foo = __floatsidf (l);
- return foo;
- }
-+#endif
-+
-
-+#ifdef __EXTENDSFDF2
- /* convert float to double */
- double
- __extendsfdf2 (float a1)
-@@ -268,7 +283,9 @@ __extendsfdf2 (float a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __TRUNCDFSF2
- /* convert double to float */
- float
- __truncdfsf2 (double a1)
-@@ -336,7 +353,9 @@ __truncdfsf2 (double a1)
- fl.l = PACK (SIGND (dl1), exp, mant);
- return (fl.f);
- }
-+#endif
-
-+#ifdef __FIXDFSI
- /* convert double to int */
- long
- __fixdfsi (double a1)
-@@ -368,7 +387,9 @@ __fixdfsi (double a1)
-
- return (SIGND (dl1) ? -l : l);
- }
-+#endif
-
-+#ifdef __FIXSFSI
- /* convert float to int */
- long
- __fixsfsi (float a1)
-@@ -376,6 +397,7 @@ __fixsfsi (float a1)
- double foo = a1;
- return __fixdfsi (foo);
- }
-+#endif
-
- #else /* EXTFLOAT */
-
-@@ -396,6 +418,8 @@ float __truncdfsf2 (double);
- long __fixdfsi (double);
- long __fixsfsi (float);
-
-+#if !defined(EXTFLOATCMP)
-+
- int
- __unordxf2(long double a, long double b)
- {
-@@ -445,38 +469,6 @@ __extenddfxf2 (double d)
- return ldl.ld;
- }
-
--/* convert long double to double */
--double
--__truncxfdf2 (long double ld)
--{
-- register long exp;
-- register union double_long dl;
-- register union long_double_long ldl;
--
-- ldl.ld = ld;
-- /*printf ("xfdf in: %s\n", dumpxf (ld));*/
--
-- dl.l.upper = SIGNX (ldl);
-- if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle &&
!ldl.l.lower)
-- {
-- dl.l.lower = 0;
-- return dl.d;
-- }
--
-- exp = EXPX (ldl) - EXCESSX + EXCESSD;
-- /* ??? quick and dirty: keep `exp' sane */
-- if (exp >= EXPDMASK)
-- exp = EXPDMASK - 1;
-- dl.l.upper |= exp << (32 - (EXPDBITS + 1));
-- /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */
-- dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
-- dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1));
-- dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1);
--
-- /*printf ("xfdf out: %g\n", dl.d);*/
-- return dl.d;
--}
--
- /* convert a float to a long double */
- long double
- __extendsfxf2 (float f)
-@@ -549,6 +541,8 @@ __negxf2 (long double x1)
- return - (double) x1;
- }
-
-+#else
-+
- long
- __cmpxf2 (long double x1, long double x2)
- {
-@@ -591,5 +585,38 @@ __gexf2 (long double x1, long double x2)
- return __cmpdf2 ((double) x1, (double) x2);
- }
-
-+/* convert long double to double */
-+double
-+__truncxfdf2 (long double ld)
-+{
-+ register long exp;
-+ register union double_long dl;
-+ register union long_double_long ldl;
-+
-+ ldl.ld = ld;
-+ /*printf ("xfdf in: %s\n", dumpxf (ld));*/
-+
-+ dl.l.upper = SIGNX (ldl);
-+ if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle &&
!ldl.l.lower)
-+ {
-+ dl.l.lower = 0;
-+ return dl.d;
-+ }
-+
-+ exp = EXPX (ldl) - EXCESSX + EXCESSD;
-+ /* ??? quick and dirty: keep `exp' sane */
-+ if (exp >= EXPDMASK)
-+ exp = EXPDMASK - 1;
-+ dl.l.upper |= exp << (32 - (EXPDBITS + 1));
-+ /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */
-+ dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
-+ dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1));
-+ dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1);
-+
-+ /*printf ("xfdf out: %g\n", dl.d);*/
-+ return dl.d;
-+}
-+#endif /* EXTFLOATCMP */
-+
- #endif /* !__mcoldfire__ */
- #endif /* EXTFLOAT */
-diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib
-index 1ee8782d9fd2..2365433a59b3 100644
---- libgcc/config/m68k/t-floatlib
-+++ libgcc/config/m68k/t-floatlib
-@@ -1,11 +1,62 @@
--LIB1ASMSRC = m68k/lb1sf68.S
--LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-- _double _float _floatex \
-- _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-- _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-+#LIB1ASMSRC = m68k/lb1sf68.S
-+#LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-+# _double _float _floatex \
-+# _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-+# _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-
--LIB2ADD = $(srcdir)/config/m68k/fpgnulib.c xfgnulib.c
-+LIB2ADD = xfpgnulib.c xfpgnulib__unordsf2.c xfpgnulib__unorddf2.c \
-+ xfpgnulib__floatunsidf.c xfpgnulib__floatsidf.c xfpgnulib__floatunsisf.c \
-+ xfpgnulib__floatsisf.c xfpgnulib__extendsfdf2.c xfpgnulib__truncdfsf2.c \
-+ xfpgnulib__fixdfsi.c xfpgnulib__fixsfsi.c xfpgnulib__cmpxf2.c
-
--xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define EXTFLOAT' > xfgnulib.c
-- cat $< >> xfgnulib.c
-+xfpgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDSF2' > xfpgnulib__unordsf2.c
-+ cat $< >> xfpgnulib__unordsf2.c
-+
-+xfpgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDDF2' > xfpgnulib__unorddf2.c
-+ cat $< >> xfpgnulib__unorddf2.c
-+
-+xfpgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSIDF' > xfpgnulib__floatunsidf.c
-+ cat $< >> xfpgnulib__floatunsidf.c
-+
-+xfpgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSIDF' > xfpgnulib__floatsidf.c
-+ cat $< >> xfpgnulib__floatsidf.c
-+
-+xfpgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSISF' > xfpgnulib__floatunsisf.c
-+ cat $< >> xfpgnulib__floatunsisf.c
-+
-+xfpgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSISF' > xfpgnulib__floatsisf.c
-+ cat $< >> xfpgnulib__floatsisf.c
-+
-+xfpgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __EXTENDSFDF2' > xfpgnulib__extendsfdf2.c
-+ cat $< >> xfpgnulib__extendsfdf2.c
-+
-+xfpgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __TRUNCDFSF2' > xfpgnulib__truncdfsf2.c
-+ cat $< >> xfpgnulib__truncdfsf2.c
-+
-+xfpgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXDFSI' > xfpgnulib__fixdfsi.c
-+ cat $< >> xfpgnulib__fixdfsi.c
-+
-+xfpgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXSFSI' > xfpgnulib__fixsfsi.c
-+ cat $< >> xfpgnulib__fixsfsi.c
-+
-+xfpgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define EXTFLOAT' > xfpgnulib.c
-+ cat $< >> xfpgnulib.c
-+
-+xfpgnulib__cmpxf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define EXTFLOAT' > xfpgnulib__cmpxf2.c
-+ echo '#define EXTFLOATCMP' >> xfpgnulib__cmpxf2.c
-+ cat $< >> xfpgnulib__cmpxf2.c
-+
-\ No newline at end of file
-diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
-index 1fb6026d123f..7bf0e4236f64 100644
---- libgcc/unwind-dw2.c
-+++ libgcc/unwind-dw2.c
-@@ -260,6 +260,9 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
- }
-
- /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
-+#ifdef TARGET_AMIGA
-+static int overregs[16];
-+#endif
-
- inline void
- _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
-@@ -271,6 +274,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index,
_Unwind_Word val)
- gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- size = dwarf_reg_size_table[index];
-
-+#ifdef TARGET_AMIGA
-+ overregs[index] = val;
-+#endif
- if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- {
- context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
-@@ -279,6 +285,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index,
_Unwind_Word val)
-
- ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
-
-+ if (!ptr)
-+ return;
-+
- if (size == sizeof(_Unwind_Ptr))
- * (_Unwind_Ptr *) ptr = val;
- else
-@@ -1612,10 +1621,10 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
- macro because __builtin_eh_return must be invoked in the context of
- our caller. */
-
--#define uw_install_context(CURRENT, TARGET) \
-+#define uw_install_context(CURRENT, TARGET, INDEX) \
- do \
- { \
-- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
-+ long offset = uw_install_context_1 ((CURRENT), (TARGET), (INDEX)); \
- void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
- _Unwind_DebugHook ((TARGET)->cfa, handler); \
- __builtin_eh_return (offset, handler); \
-@@ -1624,7 +1633,8 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
-
- static long
- uw_install_context_1 (struct _Unwind_Context *current,
-- struct _Unwind_Context *target)
-+ struct _Unwind_Context *target,
-+ int index ATTRIBUTE_UNUSED)
- {
- long i;
- _Unwind_SpTmp sp_slot;
-@@ -1659,7 +1669,75 @@ uw_install_context_1 (struct _Unwind_Context *current,
- else if (t && c && t != c)
- memcpy (c, t, dwarf_reg_size_table[i]);
- }
-+#ifdef __AMIGA__
-+ /* SBF: evil hack to patch the values for d0/d1 into the stack location.
-+ * search the movem insn and count the saved regs.
-+ * Now patch the values into location.
-+ * Always patch d0/d1 since override is always invoked for d0/d1.
-+ * Then patch all other regs which the above code omitted.
-+ */
-+ /* uw_install_context_1 is called from 4 different locations - each uses an unique
index.
-+ * So initialization is only done once.
-+ */
-+ static unsigned short counts[4];
-+ static unsigned short masks[4];
-+
-+ unsigned short count = 0;
-+ unsigned short reg_mask = masks[index];
-+ /* init each index once. */
-+ if (!reg_mask)
-+ {
-+ /* get the return address.*/
-+ unsigned short * sp = *(((unsigned short **)¤t) - 1);
-+ /* search the movem -x(a5),regs insn.*/
-+ for (;;)
-+ {
-+ unsigned short s = *sp++;
-+// printf("%04x ", s);
-+ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch!
-+ if (s == (unsigned short)0x4ced)
-+ break;
-+ }
-+ reg_mask = *sp;
-+ /* count saved regs */
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ ++count;
-+ m >>= 1;
-+ }
-+ masks[index] = reg_mask;
-+ counts[index] = count;
-+ }
-+ else
-+ count = counts[index];
-
-+ /* regs are saved below local vars -> start at current */
-+ int * p = ((int *)current) - count;
-+
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ {
-+ if (i <= 1 || (!current->reg[i] && (target->reg[i] ||
target->by_value[i])))
-+ {
-+ int old = *p;
-+ /* not set by the code above - set it here */
-+ if (i <= 1) // use the override values for d0/d1
-+ *p = overregs[i];
-+ else
-+ if (target->by_value[i])
-+ *p = (int)target->reg[i];
-+ else
-+ *p = *(int*)target->reg[i];
-+// printf("patch reg %d from %08lx to %08lx\n", i, old, *p);
-+ }
-+ ++p;
-+ }
-+ m >>= 1;
-+ }
-+
-+#endif
- /* If the current frame doesn't have a saved stack pointer, then we
- need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
- pointer value reloaded. */
-diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
-index 7413b55e3fab..bf07725ac840 100644
---- libgcc/unwind.inc
-+++ libgcc/unwind.inc
-@@ -132,7 +132,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 0);
- }
-
-
-@@ -208,7 +208,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 1);
- }
-
-
-@@ -233,7 +233,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 2);
- }
-
-
-@@ -258,7 +258,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 3);
- }
-
-
-diff --git a/libiberty/lrealpath.c b/libiberty/lrealpath.c
-index b27c8de990e9..78c06e46da58 100644
---- libiberty/lrealpath.c
-+++ libiberty/lrealpath.c
-@@ -73,7 +73,7 @@ extern char *canonicalize_file_name (const char *);
- #endif
-
- char *
--lrealpath (const char *filename)
-+__xlrealpath (const char *filename)
- {
- /* Method 1: The system has a compile time upper bound on a filename
- path. Use that and realpath() to canonicalize the name. This is
-@@ -155,3 +155,19 @@ lrealpath (const char *filename)
- /* This system is a lost cause, just duplicate the filename. */
- return strdup (filename);
- }
-+
-+
-+char *
-+lrealpath (const char *filename)
-+{
-+ char * r = __xlrealpath(filename);
-+#if defined (_WIN32)
-+ if (strncmp(r, "/cygdrive/", 10) == 0)
-+ {
-+ r[9] = r[10];
-+ r[10] = ':';
-+ r = strdup(&r[9]);
-+ }
-+#endif
-+ return r;
-+}
-diff --git a/libobjc/configure b/libobjc/configure
-index 55fcc33dbe2d..a60258f422d8 100755
---- libobjc/configure
-+++ libobjc/configure
-@@ -7637,7 +7637,8 @@ $as_echo_n "checking for $compiler option to produce PIC...
" >&6; }
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
-- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ #lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
- ;;
- esac
- ;;
-diff --git a/libobjc/objc/objc.h b/libobjc/objc/objc.h
-index 37391a446bb0..6c73f53290e8 100644
---- libobjc/objc/objc.h
-+++ libobjc/objc/objc.h
-@@ -52,7 +52,11 @@ extern "C" {
- Important: this could change and we could switch to 'typedef bool
- BOOL' in the future. Do not depend on the type of BOOL. */
- #undef BOOL
-+#ifdef AMIGA
-+typedef short BOOL;
-+#else
- typedef unsigned char BOOL;
-+#endif
-
- #define YES (BOOL)1
- #define NO (BOOL)0
-diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-index 903de5625d77..ed0c757d42f8 100644
---- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-+++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-@@ -65,6 +65,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
- _M_narrow_ok = 0;
- }
-
-+#ifdef __AMIGA__
-+ ctype<char>::~ctype()
-+ {
-+ _S_destroy_c_locale(_M_c_locale_ctype);
-+ if (_M_del)
-+ delete[] this->table();
-+ }
-+#endif
-+
- char
- ctype<char>::do_toupper(char __c) const
- {
-diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
-index 9bf152a01573..f162705f2625 100755
---- libstdc++-v3/configure
-+++ libstdc++-v3/configure
-@@ -8636,6 +8636,8 @@ $as_echo_n "checking for $compiler option to produce PIC...
" >&6; }
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
-+ CXXFLAGS="$CXXFLAGS -noixemul"
- ;;
- esac
- ;;
-@@ -28883,6 +28885,10 @@ else
-
- # Base decisions on target environment.
- case "${host}" in
-+ m68k-*-*)
-+ # Nothing to do here.
-+ ;;
-+
- arm*-*-symbianelf*)
- # This is a freestanding configuration; there is nothing to do here.
- ;;
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 304a7f5aff61..fde4a72bd31b 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -226,6 +226,11 @@ case "${host_os}" in
- os_include_dir="os/generic"
- atomicity_dir="cpu/generic"
- ;;
-+ amiga*)
-+ os_include_dir="os/newlib"
-+ CFLAGS="-Os -noixemul"
-+ CPPFLAGS="-Os -noixemul"
-+ ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
- os_include_dir="os/bsd/freebsd"
-diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint
-index 7304d9008413..7d6ab77ce17a 100644
---- libstdc++-v3/include/tr1/cstdint
-+++ libstdc++-v3/include/tr1/cstdint
-@@ -30,7 +30,9 @@
- #define _GLIBCXX_TR1_CSTDINT 1
-
- #pragma GCC system_header
--
-+#ifdef AMIGA
-+#include <stdint.h>
-+#endif
- #include <bits/c++config.h>
-
- // For 8.22.1/1 (see C99, Notes 219, 220, 222)
-diff --git a/libstdc++-v3/src/c++11/ctype.cc b/libstdc++-v3/src/c++11/ctype.cc
-index fa370681dad5..f80e83034255 100644
---- libstdc++-v3/src/c++11/ctype.cc
-+++ libstdc++-v3/src/c++11/ctype.cc
-@@ -51,12 +51,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- const size_t ctype<char>::table_size;
-
-+#ifndef __AMIGA__
-+/* moved to ctype_configure_char */
- ctype<char>::~ctype()
- {
- _S_destroy_c_locale(_M_c_locale_ctype);
- if (_M_del)
- delete[] this->table();
- }
-+#endif
-
- // Fill in the narrowing cache and flag whether all values are
- // valid or not. _M_narrow_ok is set to 2 if memcpy can't
-----------------------------------------------------------------------
Summary of changes:
m68k-unknown-amigaos/Makefile | 11 +-
m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p |11008 -----------------------
2 files changed, 4 insertions(+), 11015 deletions(-)
delete mode 100644 m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
diff --git a/m68k-unknown-amigaos/Makefile b/m68k-unknown-amigaos/Makefile
index 8a54b86..31df799 100644
--- a/m68k-unknown-amigaos/Makefile
+++ b/m68k-unknown-amigaos/Makefile
@@ -3,9 +3,9 @@
# sources
-UPSTREAM_GCC_VERSION := 6.4.0
-UPSTREAM_GCC_TARBALL := gcc-$(UPSTREAM_GCC_VERSION).tar.xz
-UPSTREAM_GCC_URI :=
http://ftp.gnu.org/gnu/gcc/gcc-$(UPSTREAM_GCC_VERSION)/$(UPSTREAM_GCC_TAR...
+UPSTREAM_GCC_VERSION := 6.4.1b-20180122
+UPSTREAM_GCC_TARBALL := v$(UPSTREAM_GCC_VERSION).tar.gz
+UPSTREAM_GCC_URI :=
https://github.com/chris-y/gcc/archive/$(UPSTREAM_GCC_TARBALL)
UPSTREAM_BINUTILS_VERSION := 2.14
# Not a tarball; so sue me
@@ -156,9 +156,6 @@ $(BUILDSTEPS)/bootstrap-compiler.d: $(BUILDSTEPS)/bison.d
$(BUILDSTEPS)/srcdir-s
###
$(BUILDSTEPS)/srcdir-step3.d: $(BUILDSTEPS)/srcdir-step2.d
- for p in `ls $(RECIPES)/patches/gcc/*.p` ; do patch -d $(GCC_SRCDIR) -p0 <$$p ; done
- for dir in `find $(RECIPES)/files/gcc/ -type d | grep -v '\.svn' | sed
's#$(RECIPES)/files/gcc##'` ; do mkdir -p $(GCC_SRCDIR)$$dir ; done
- for file in `find $(RECIPES)/files/gcc/ -type f | grep -v '\.svn' | sed
's#$(RECIPES)/files/gcc##'` ; do cp -p $(RECIPES)/files/gcc$$file
$(GCC_SRCDIR)$$file ; done
touch $(GCC_SRCDIR)/lto-plugin/aclocal.m4 $(GCC_SRCDIR)/lto-plugin/Makefile.in
touch $(GCC_SRCDIR)/zlib/aclocal.m4 $(GCC_SRCDIR)/zlib/Makefile.in
touch $(GCC_SRCDIR)/libbacktrace/aclocal.m4 $(GCC_SRCDIR)/libbacktrace/Makefile.in
@@ -177,7 +174,7 @@ $(BUILDSTEPS)/srcdir-step2.d: $(BUILDSTEPS)/srcdir-step1.d
$(SOURCESDIR)/$(UPSTR
touch $@
$(BUILDSTEPS)/srcdir-step1.d: $(BUILDSTEPS)/$(UPSTREAM_GCC_TARBALL).d
- tar xJf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
+ tar xzf $(SOURCESDIR)/$(UPSTREAM_GCC_TARBALL)
mv gcc-$(UPSTREAM_GCC_VERSION) $(GCC_SRCDIR)
touch $@
diff --git a/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
b/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
deleted file mode 100644
index 25088ee..0000000
--- a/m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p
+++ /dev/null
@@ -1,11008 +0,0 @@
-diff --git a/.cproject b/.cproject
-new file mode 100755
-index 000000000000..6db4cbe2447e
---- /dev/null
-+++ .cproject
-@@ -0,0 +1,188 @@
-+<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
-+<?fileVersion 4.0.0?><cproject
storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
-+ <storageModule moduleId="org.eclipse.cdt.core.settings">
-+ <cconfiguration
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522">
-+ <storageModule
buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider"
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
moduleId="org.eclipse.cdt.core.settings" name="Debug">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.Cygwin_PE"
point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}"
buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe"
buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug"
cleanCommand="rm -rf" description=""
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
name="Debug" parent="cdt.managedbuild.config.gnu.cross.exe.debug">
-+ <folderInfo
id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522." name="/"
resourcePath="">
-+ <toolChain id="cdt.managedbuild.toolchain.gnu.cygwin.base.2053847551"
name="Cygwin GCC"
superClass="cdt.managedbuild.toolchain.gnu.cygwin.base">
-+ <targetPlatform archList="all"
binaryParser="org.eclipse.cdt.core.Cygwin_PE"
id="cdt.managedbuild.target.gnu.platform.cygwin.base.2091243283"
name="Debug Platform" osList="win32"
superClass="cdt.managedbuild.target.gnu.platform.cygwin.base"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Debug"
id="cdt.managedbuild.target.gnu.builder.cygwin.base.1660320342"
keepEnvironmentInBuildfile="false" managedBuildOn="false"
name="Gnu Make Builder"
superClass="cdt.managedbuild.target.gnu.builder.cygwin.base">
-+ <outputEntries>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED"
kind="outputPath" name=""/>
-+ </outputEntries>
-+ </builder>
-+ <tool id="cdt.managedbuild.tool.gnu.assembler.cygwin.base.607722454"
name="GCC Assembler"
superClass="cdt.managedbuild.tool.gnu.assembler.cygwin.base">
-+ <option id="gnu.both.asm.option.include.paths.2094451885"
name="Include paths (-I)"
superClass="gnu.both.asm.option.include.paths"
valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/amigaos-cross-toolchain/.build-m68k/build/gcc-6/gcc}""/>
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.assembler.input.1425989952"
superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.archiver.cygwin.base.2119049474"
name="GCC Archiver"
superClass="cdt.managedbuild.tool.gnu.archiver.cygwin.base"/>
-+ <tool
id="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968"
name="Cygwin C++ Compiler"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base">
-+ <option id="gnu.cpp.compiler.option.include.paths.466783605"
name="Include paths (-I)"
superClass="gnu.cpp.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/gcc-6/libcpp/include}""/>
-+ <listOptionValue builtIn="false"
value=""D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc""/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.optimization.level.193715843"
name="Optimization Level"
superClass="gnu.cpp.compiler.option.optimization.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.optimization.level.none"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.2136883244"
name="Debug Level"
superClass="gnu.cpp.compiler.option.debugging.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.debugging.level.max"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.807277038"
name="Defined symbols (-D)"
superClass="gnu.cpp.compiler.option.preprocessor.def"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin"/>
-+ </tool>
-+ <tool
id="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604"
name="Cygwin C Compiler"
superClass="cdt.managedbuild.tool.gnu.c.compiler.cygwin.base">
-+ <option id="gnu.c.compiler.option.include.paths.692774379"
name="Include paths (-I)"
superClass="gnu.c.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ <listOptionValue builtIn="false"
value=""${workspace_loc:/gcc-6/libcpp/include}""/>
-+ <listOptionValue builtIn="false"
value=""D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc""/>
-+ </option>
-+ <option defaultValue="gnu.c.optimization.level.none"
id="gnu.c.compiler.option.optimization.level.227992926" name="Optimization
Level" superClass="gnu.c.compiler.option.optimization.level"
useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.748883400"
name="Debug Level" superClass="gnu.c.compiler.option.debugging.level"
useByScannerDiscovery="false" value="gnu.c.debugging.level.max"
valueType="enumerated"/>
-+ <option
id="gnu.c.compiler.option.preprocessor.def.symbols.1982594045"
name="Defined symbols (-D)"
superClass="gnu.c.compiler.option.preprocessor.def.symbols"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313"
superClass="cdt.managedbuild.tool.gnu.c.compiler.input.cygwin"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.c.linker.cygwin.base.344641511"
name="Cygwin C Linker"
superClass="cdt.managedbuild.tool.gnu.c.linker.cygwin.base"/>
-+ <tool
id="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base.968200320"
name="Cygwin C++ Linker"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.cygwin.base">
-+ <option id="gnu.cpp.link.option.libs.260033787"
name="Libraries (-l)" superClass="gnu.cpp.link.option.libs"/>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.linker.input.1537937183"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency"
paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput"
paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry
excluding="ada/|doc/|fortran/|ginclude/|go/|java/|jit/|lto/|objc/|objcp/|po/|testsuite/|config/aarch64/|config/alpha/|config/arc/|config/arm/|config/avr/|config/bfin/|config/c6x/|config/cr16/|config/cris/|config/epiphany/|config/fr30/|config/frv/|config/ft32/|config/h8300/|config/i386/|config/ia64/|config/iq2000/|config/lm32/|config/m32c/|config/m32r/|config/mcore/|config/mep/|config/microblaze/|config/mips/|config/mmix/|config/mn10300/|config/moxie/|config/msp430/|config/nds32/|config/nios2/|config/nvptx/|config/pa/|config/pdp11/|config/rl78/|config/rs6000/|config/rx/|config/s390/|config/sh/|config/sparc/|config/spu/|config/stormy16/|config/tilegx/|config/tilepro/|config/v850/|config/vax/|config/visium/|config/vms/|config/xtensa/"
flags="VALUE_WORKSPACE_PATH" kind="sourcePath"
name="gcc"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ <cconfiguration
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954">
-+ <storageModule
buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider"
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
moduleId="org.eclipse.cdt.core.settings" name="Release">
-+ <externalSettings/>
-+ <extensions>
-+ <extension id="org.eclipse.cdt.core.ELF"
point="org.eclipse.cdt.core.BinaryParser"/>
-+ <extension id="org.eclipse.cdt.core.GASErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GmakeErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.CWDLocator"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GCCErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ <extension id="org.eclipse.cdt.core.GLDErrorParser"
point="org.eclipse.cdt.core.ErrorParser"/>
-+ </extensions>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <configuration artifactName="${ProjName}"
buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe"
buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release"
cleanCommand="rm -rf" description=""
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
name="Release"
parent="cdt.managedbuild.config.gnu.cross.exe.release">
-+ <folderInfo
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954." name="/"
resourcePath="">
-+ <toolChain
id="cdt.managedbuild.toolchain.gnu.cross.exe.release.101222491" name="Cross
GCC" superClass="cdt.managedbuild.toolchain.gnu.cross.exe.release">
-+ <targetPlatform archList="all"
binaryParser="org.eclipse.cdt.core.ELF"
id="cdt.managedbuild.targetPlatform.gnu.cross.1798723854"
isAbstract="false" osList="all"
superClass="cdt.managedbuild.targetPlatform.gnu.cross"/>
-+ <builder buildPath="${workspace_loc:/debugwin}/Release"
id="cdt.managedbuild.builder.gnu.cross.507087034"
keepEnvironmentInBuildfile="false" managedBuildOn="true"
name="Gnu Make Builder"
superClass="cdt.managedbuild.builder.gnu.cross"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466"
name="Cross GCC Compiler"
superClass="cdt.managedbuild.tool.gnu.cross.c.compiler">
-+ <option defaultValue="gnu.c.optimization.level.most"
id="gnu.c.compiler.option.optimization.level.1686563067" name="Optimization
Level" superClass="gnu.c.compiler.option.optimization.level"
useByScannerDiscovery="false" valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.debugging.level.60172226"
name="Debug Level" superClass="gnu.c.compiler.option.debugging.level"
useByScannerDiscovery="false" value="gnu.c.debugging.level.none"
valueType="enumerated"/>
-+ <option id="gnu.c.compiler.option.include.paths.696908692"
name="Include paths (-I)"
superClass="gnu.c.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <option
id="gnu.c.compiler.option.preprocessor.def.symbols.652362073" name="Defined
symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.c.compiler.input.1150724656"
superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749"
name="Cross G++ Compiler"
superClass="cdt.managedbuild.tool.gnu.cross.cpp.compiler">
-+ <option id="gnu.cpp.compiler.option.optimization.level.2088586809"
name="Optimization Level"
superClass="gnu.cpp.compiler.option.optimization.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.optimization.level.most"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.debugging.level.1993778911"
name="Debug Level"
superClass="gnu.cpp.compiler.option.debugging.level"
useByScannerDiscovery="false"
value="gnu.cpp.compiler.debugging.level.none"
valueType="enumerated"/>
-+ <option id="gnu.cpp.compiler.option.include.paths.1936413739"
name="Include paths (-I)"
superClass="gnu.cpp.compiler.option.include.paths"
useByScannerDiscovery="false" valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <option id="gnu.cpp.compiler.option.preprocessor.def.625117841"
name="Defined symbols (-D)"
superClass="gnu.cpp.compiler.option.preprocessor.def"
useByScannerDiscovery="false" valueType="definedSymbols">
-+ <listOptionValue builtIn="false" value="IN_GCC=1"/>
-+ <listOptionValue builtIn="false"
value="HAVE_cc0=1"/>
-+ <listOptionValue builtIn="false"
value="__ECLIPSE__=1"/>
-+ <listOptionValue builtIn="false"
value="TARGET_AMIGA=1"/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.c.linker.946489608"
name="Cross GCC Linker"
superClass="cdt.managedbuild.tool.gnu.cross.c.linker"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.cpp.linker.738916918"
name="Cross G++ Linker"
superClass="cdt.managedbuild.tool.gnu.cross.cpp.linker">
-+ <inputType
id="cdt.managedbuild.tool.gnu.cpp.linker.input.1880308865"
superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
-+ <additionalInput kind="additionalinputdependency"
paths="$(USER_OBJS)"/>
-+ <additionalInput kind="additionalinput"
paths="$(LIBS)"/>
-+ </inputType>
-+ </tool>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.archiver.1813524686"
name="Cross GCC Archiver"
superClass="cdt.managedbuild.tool.gnu.cross.archiver"/>
-+ <tool id="cdt.managedbuild.tool.gnu.cross.assembler.1395544547"
name="Cross GCC Assembler"
superClass="cdt.managedbuild.tool.gnu.cross.assembler">
-+ <option id="gnu.both.asm.option.include.paths.1443815690"
name="Include paths (-I)"
superClass="gnu.both.asm.option.include.paths"
valueType="includePath">
-+ <listOptionValue builtIn="false"
value=""C:\cygwin\usr\include""/>
-+ </option>
-+ <inputType
id="cdt.managedbuild.tool.gnu.assembler.input.1421786104"
superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
-+ </tool>
-+ </toolChain>
-+ </folderInfo>
-+ <sourceEntries>
-+ <entry excluding="src"
flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath"
name=""/>
-+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED"
kind="sourcePath" name="src"/>
-+ </sourceEntries>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
-+ </cconfiguration>
-+ </storageModule>
-+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-+ <project id="debugwin.cdt.managedbuild.target.gnu.cross.exe.1884740625"
name="Executable"
projectType="cdt.managedbuild.target.gnu.cross.exe"/>
-+ </storageModule>
-+ <storageModule
moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
-+ <storageModule moduleId="refreshScope" versionNumber="2">
-+ <configuration configurationName="Debug">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ <configuration configurationName="Release">
-+ <resource resourceType="PROJECT" workspacePath="/gcc-6"/>
-+ </configuration>
-+ </storageModule>
-+ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
-+ <storageModule moduleId="scannerConfiguration">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.c.compiler.1834281466;cdt.managedbuild.tool.gnu.c.compiler.input.1150724656">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.c.compiler.502147450;cdt.managedbuild.tool.gnu.c.compiler.input.1173428818">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cpp.compiler.cygwin.base.1103847968;cdt.managedbuild.tool.gnu.cpp.compiler.input.cygwin.780175803">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.c.compiler.cygwin.base.1920331604;cdt.managedbuild.tool.gnu.c.compiler.input.cygwin.2078467313">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.debug.452878522;cdt.managedbuild.config.gnu.cross.exe.debug.452878522.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.216739552;cdt.managedbuild.tool.gnu.cpp.compiler.input.1269341019">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ <scannerConfigBuildInfo
instanceId="cdt.managedbuild.config.gnu.cross.exe.release.811454954;cdt.managedbuild.config.gnu.cross.exe.release.811454954.;cdt.managedbuild.tool.gnu.cross.cpp.compiler.1042604749;cdt.managedbuild.tool.gnu.cpp.compiler.input.1133865092">
-+ <autodiscovery enabled="true" problemReportingEnabled="true"
selectedProfileId=""/>
-+ </scannerConfigBuildInfo>
-+ </storageModule>
-+</cproject>
-diff --git a/.project b/.project
-new file mode 100644
-index 000000000000..500c9ee08dca
---- /dev/null
-+++ .project
-@@ -0,0 +1,34 @@
-+<?xml version="1.0" encoding="UTF-8"?>
-+<projectDescription>
-+ <name>gcc-6</name>
-+ <comment></comment>
-+ <projects>
-+ </projects>
-+ <buildSpec>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-+ <triggers>clean,full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
-+ <buildCommand>
-+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
-+ <triggers>full,incremental,</triggers>
-+ <arguments>
-+ </arguments>
-+ </buildCommand>
-+ </buildSpec>
-+ <natures>
-+ <nature>org.eclipse.cdt.core.cnature</nature>
-+ <nature>org.eclipse.cdt.core.ccnature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
-+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
-+ </natures>
-+ <linkedResources>
-+ <link>
-+ <name>build-gcc</name>
-+ <type>2</type>
-+ <location>D:/develop/workspaces/c1/amigaos-cross-toolchain/.build-m68k/build/gcc-6</location>
-+ </link>
-+ </linkedResources>
-+</projectDescription>
-diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml
-new file mode 100755
-index 000000000000..caef162d88d1
---- /dev/null
-+++ .settings/language.settings.xml
-@@ -0,0 +1,25 @@
-+<?xml version="1.0" encoding="UTF-8"
standalone="no"?>
-+<project>
-+ <configuration id="cdt.managedbuild.config.gnu.cross.exe.debug.452878522"
name="Debug">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension"
id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference
id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider-reference
id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider
class="org.eclipse.cdt.managedbuilder.internal.language.settings.providers.GCCBuiltinSpecsDetectorCygwin"
console="false" env-hash="1253352314297216180"
id="org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetectorCygwin"
keep-relative-paths="false" name="CDT GCC Built-in Compiler Settings
Cygwin" parameter="${COMMAND} ${FLAGS} -E -P -v -dD
"${INPUTS}"" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+ <configuration
id="cdt.managedbuild.config.gnu.cross.exe.release.811454954"
name="Release">
-+ <extension point="org.eclipse.cdt.core.LanguageSettingsProvider">
-+ <provider copy-of="extension"
id="org.eclipse.cdt.ui.UserLanguageSettingsProvider"/>
-+ <provider-reference
id="org.eclipse.cdt.core.ReferencedProjectsLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider-reference
id="org.eclipse.cdt.managedbuilder.core.MBSLanguageSettingsProvider"
ref="shared-provider"/>
-+ <provider
class="org.eclipse.cdt.internal.build.crossgcc.CrossGCCBuiltinSpecsDetector"
console="false" env-hash="-910044784883564564"
id="org.eclipse.cdt.build.crossgcc.CrossGCCBuiltinSpecsDetector"
keep-relative-paths="false" name="CDT Cross GCC Built-in Compiler
Settings" parameter="${COMMAND} ${FLAGS} -E -P -v -dD
"${INPUTS}"" prefer-non-shared="true">
-+ <language-scope id="org.eclipse.cdt.core.gcc"/>
-+ <language-scope id="org.eclipse.cdt.core.g++"/>
-+ </provider>
-+ </extension>
-+ </configuration>
-+</project>
-diff --git a/.settings/org.eclipse.cdt.codan.core.prefs
b/.settings/org.eclipse.cdt.codan.core.prefs
-new file mode 100755
-index 000000000000..b5248c620107
---- /dev/null
-+++ .settings/org.eclipse.cdt.codan.core.prefs
-@@ -0,0 +1,71 @@
-+eclipse.preferences.version=1
-+org.eclipse.cdt.codan.checkers.errnoreturn=Warning
-+org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
return\\")",implicit\=>false}
-+org.eclipse.cdt.codan.checkers.errreturnvalue=Error
-+org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
return value\\")"}
-+org.eclipse.cdt.codan.checkers.nocommentinside=-Error
-+org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Nesting
comments\\")"}
-+org.eclipse.cdt.codan.checkers.nolinecomment=-Error
-+org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Line
comments\\")"}
-+org.eclipse.cdt.codan.checkers.noreturn=Error
-+org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
return value\\")",implicit\=>false}
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
-+org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Abstract
class cannot be instantiated\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Ambiguous
problem\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment
in condition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Assignment
to itself\\")"}
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"No
break at end of case\\")",no_break_comment\=>"no
break",last_case_param\=>false,empty_case_param\=>false}
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
-+org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Catching
by reference is recommended\\")",unknown\=>false,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Circular
inheritance\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
-+org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class
members should be properly initialized\\")",skip\=>true}
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Field
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Function
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
arguments\\")"}
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
template argument\\")"}
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Label
statement not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Member
declaration not found\\")"}
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Method
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
-+org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Name
convention for
function\\")",pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Class
has a virtual method and non-virtual destructor\\")"}
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
overload\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
redeclaration\\")"}
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Invalid
redefinition\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Return
with parenthesis\\")"}
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
-+org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Format
String Vulnerability\\")"}
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Statement
has no effect\\")",macro\=>true,exceptions\=>()}
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suggested
parenthesis around expression\\")",paramNot\=>false}
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Suspicious
semicolon\\")",else\=>false,afterelse\=>false}
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Type
cannot be resolved\\")"}
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
function declaration\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
static function\\")",macro\=>true}
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
-+org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Unused
variable declaration in file
scope\\")",macro\=>true,exceptions\=>("@(\#)","$Id")}
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
-+org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},suppression_comment\=>"@suppress(\\"Symbol
is not resolved\\")"}
-diff --git a/.settings/org.eclipse.cdt.core.prefs b/.settings/org.eclipse.cdt.core.prefs
-new file mode 100755
-index 000000000000..8ec9fe72ca59
---- /dev/null
-+++ .settings/org.eclipse.cdt.core.prefs
-@@ -0,0 +1,6 @@
-+eclipse.preferences.version=1
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/delimiter=;
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/operation=replace
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/PATH/value=C\:\\WINDOWS\\system32;C\:\\WINDOWS;C\:\\Program
Files\\SlikSvn\\bin;C\:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0;c\:\\cygwin\\bin;D\:\\develop\\workspaces\\c1\\amigaos-cross-toolchain\\m68k-amigaos\\bin
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/append=true
-+environment/project/cdt.managedbuild.config.gnu.cross.exe.debug.452878522/appendContributed=true
-diff --git a/.settings/org.eclipse.core.runtime.prefs
b/.settings/org.eclipse.core.runtime.prefs
-new file mode 100755
-index 000000000000..12511e62a174
---- /dev/null
-+++ .settings/org.eclipse.core.runtime.prefs
-@@ -0,0 +1,5 @@
-+content-types/enabled=true
-+content-types/org.eclipse.cdt.core.cHeader/file-extensions=def
-+content-types/org.eclipse.cdt.core.cxxHeader/file-extensions=h
-+content-types/org.eclipse.cdt.core.cxxSource/file-extensions=c
-+eclipse.preferences.version=1
-diff --git a/config.sub b/config.sub
-index 41146e11c6c9..35247fe0c474 100755
---- config.sub
-+++ config.sub
-@@ -2,7 +2,7 @@
- # Configuration validation subroutine script.
- # Copyright 1992-2016 Free Software Foundation, Inc.
-
--timestamp='2016-01-01'
-+timestamp='2017-04-21'
-
- # This file is free software; you can redistribute it and/or modify it
- # under the terms of the GNU General Public License as published by
-@@ -500,7 +500,7 @@ case $basic_machine in
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
-- amigaos | amigados)
-+ amigaos | amigaosvasm | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
-@@ -1380,7 +1380,7 @@ case $os in
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* | -cloudabi* | -sortix* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-+ | -clix* | -riscos* | -uniplus* | -iris* | -rt* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-diff --git a/gcc/Makefile.in b/gcc/Makefile.in
-index 51e2bc86e9a4..4aedf54bab12 100644
---- gcc/Makefile.in
-+++ gcc/Makefile.in
-@@ -1199,6 +1199,7 @@ OBJS = \
- auto-inc-dec.o \
- auto-profile.o \
- bb-reorder.o \
-+ bbb-opts.o \
- bitmap.o \
- bt-load.o \
- builtins.o \
-@@ -1986,7 +1987,7 @@ gcc-nm.c: gcc-ar.c
- cp $^ $@
-
- COLLECT2_OBJS = collect2.o collect2-aix.o tlink.o vec.o ggc-none.o \
-- collect-utils.o file-find.o hash-table.o
-+ collect-utils.o file-find.o hash-table.o $(EXTRA_COLLECT2_OBJS)
- COLLECT2_LIBS = @COLLECT2_LIBS@
- collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS)
- # Don't try modifying collect2 (aka ld) in place--it might be linking this.
-@@ -3270,7 +3271,7 @@ endif
- install-strip: install
-
- # Handle cpp installation.
--install-cpp: installdirs cpp$(exeext)
-+install-cpp: installdirs cpp$(exeext) all.cross
- -if test "$(enable_as_accelerator)" != "yes" ; then \
- rm -f $(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
- $(INSTALL_PROGRAM) -m 755 cpp$(exeext)
$(DESTDIR)$(bindir)/$(CPP_INSTALL_NAME)$(exeext); \
-diff --git a/gcc/amigacollect2.c b/gcc/amigacollect2.c
-new file mode 100755
-index 000000000000..941ea0248fbe
---- /dev/null
-+++ gcc/amigacollect2.c
-@@ -0,0 +1,348 @@
-+/* GG-local whole file: dynamic libraries */
-+/* Supplimentary functions that get compiled and linked to collect2 for
-+ AmigaOS target.
-+ Copyright (C) 1996 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+
-+/* From collect2.c: */
-+
-+void maybe_unlink(const char *);
-+void fatal_error(location_t, const char *, ...);
-+void fork_execute(const char *, char **, bool);
-+
-+extern char *c_file_name;
-+extern int debug;
-+
-+/* Local functions. */
-+
-+static void safename (char *);
-+static void add_lib (const char *);
-+static void cat (const char *, FILE *);
-+
-+/* Names of temporary files we create. */
-+#define XLIBS_C_NAME "xlibs.c"
-+#define XLIBS_O_NAME "xlibs.o"
-+#define SHARED_X_NAME "shared.x"
-+
-+/* Suffix which is prepended to "-l" options for dynamic libraries. */
-+#define DYNAMIC_LIB_SUFFIX "_ixlibrary"
-+
-+/* Structure that holds library names. */
-+struct liblist
-+{
-+ struct liblist *next;
-+ char *name;
-+ char *cname;
-+};
-+
-+/* Not zero if "-static" was specified on GCC command line or if all the
-+ libraries are static. */
-+static int flag_static=0;
-+
-+/* Not zero if linking a base relative executable. This is recognized by
-+ presence of "-m amiga_bss" on the linker's commandline. */
-+static int flag_baserel=0;
-+
-+/* Not zero if some of the specified libraries are dynamic. */
-+static int found_dynamic_libs=0;
-+
-+/* List of linker libraries. */
-+struct liblist *head = NULL;
-+
-+/* Return 1 if collect2 should do something more apart from tlink. We want it
-+ to call "postlink" and "strip" if linking with dynamic libraries.
*/
-+
-+int
-+amigaos_do_collecting (void)
-+{
-+ return !flag_static;
-+}
-+
-+/* Check for presence of "-static" on the GCC command line. We should not do
-+ collecting if this flag was specified. */
-+
-+void
-+amigaos_gccopts_hook (const char *arg)
-+{
-+ if (strncmp(arg, "-static", strlen("-static"))==0)
-+ flag_static=1;
-+}
-+
-+/* Replace unprintable characters with underscores. Used by "add_lib()". */
-+
-+static void
-+safename (char *p)
-+{
-+ if (!ISALPHA(*p))
-+ *p = '_';
-+ p++;
-+ while (*p)
-+ {
-+ if (!ISALNUM(*p))
-+ *p = '_';
-+ p++;
-+ }
-+}
-+
-+/* Add a library to the list of dynamic libraries. First make sure that the
-+ library is actually dynamic. Used by "amigaos_libname_hook()". */
-+
-+static void
-+add_lib (const char *name)
-+{
-+ struct liblist *lib;
-+ static char buf[256];
-+
-+ for (lib = head; lib; lib = lib->next)
-+ if (!strcmp(lib->name, name))
-+ return;
-+
-+ /* A2IXDIR_PREFIX is passed by "make". */
-+ sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", name);
-+ if (access(buf, R_OK))
-+ return;
-+
-+ lib = (struct liblist*)xmalloc(sizeof(struct liblist));
-+ lib->name = xstrdup(name);
-+ lib->cname = xstrdup(name);
-+ safename(lib->cname);
-+ lib->next = head;
-+ head = lib;
-+
-+ if (debug)
-+ fprintf(stderr, "found dynamic library, name: %s, cname: %s\n",
lib->name,
-+ lib->cname);
-+
-+ found_dynamic_libs=1;
-+}
-+
-+/* Check if the argument is a linker library. Call "add_lib()" if yes. */
-+
-+void
-+amigaos_libname_hook (const char *arg)
-+{
-+ int len = strlen(arg);
-+ if (flag_static)
-+ return;
-+
-+ if (len > 2 && !memcmp(arg, "-l", 2))
-+ add_lib(arg + 2);
-+ else if (len > 2 && !strcmp(arg + len - 2, ".a"))
-+ {
-+ const char *lib;
-+
-+ ((char*)arg)[len - 2] = '\0';
-+ lib = strrchr(arg, '/');
-+ if (lib == NULL)
-+ lib = strrchr(arg, ':');
-+ if (lib == NULL)
-+ lib = arg - 1;
-+ if (!strncmp(lib + 1, "lib", 3))
-+ add_lib(lib + 4);
-+ ((char *)arg)[len - 2] = '.';
-+ }
-+}
-+
-+/* Delete temporary files. */
-+
-+void
-+amigaos_collect2_cleanup (void)
-+{
-+ if (flag_static)
-+ return;
-+ maybe_unlink(XLIBS_C_NAME);
-+ maybe_unlink(XLIBS_O_NAME);
-+ maybe_unlink(SHARED_X_NAME);
-+}
-+
-+/* Copy file named by FNAME to X. */
-+
-+static void
-+cat (const char *fname, FILE *x)
-+{
-+#define BUFSIZE 16384
-+ FILE *in;
-+ static char buf[BUFSIZE];
-+ int bytes;
-+
-+ in = fopen(fname, "r");
-+ if (in == NULL)
-+ fatal_error (input_location, "%s", fname);
-+ while (!feof(in) && (bytes = fread(buf, 1, BUFSIZE, in)))
-+ fwrite(buf, 1, bytes, x);
-+ fclose(in);
-+}
-+
-+/* If no dynamic libraries were found, perform like "-static". Otherwise,
-+ create "xlibs.c", "shared.x" and invoke "gcc" to create
"xlibs.o". We also
-+ have to adjust the linker commandline. */
-+
-+void
-+amigaos_prelink_hook (const char **ld1_argv, int *strip_flag)
-+{
-+ if (flag_static)
-+ return;
-+
-+ if (!found_dynamic_libs)
-+ {
-+ flag_static=1;
-+ /* If the user has not requested "-static", but has requested
"-s",
-+ collect2 removes "-s" from the "ld1_argv", and calls
"strip" after
-+ linking. However, this would not be efficient if we linked the
-+ executable without any dynamic library. In this case, we put "-s"
-+ back. */
-+ if (*strip_flag)
-+ {
-+ /* Add "-s" as the last argument on the command line. */
-+ while (*ld1_argv)
-+ ld1_argv++;
-+ *ld1_argv++="-s";
-+ *ld1_argv=0;
-+ *strip_flag=0;
-+ }
-+ }
-+ else
-+ {
-+ FILE *x, *out;
-+ struct liblist *lib;
-+ static const char* argv[]={0, "-c", XLIBS_C_NAME, 0};
-+ const char **ld1_end, **ld1;
-+
-+ /* Prepend suffixes to dynamic lib names. In addition, check if we are
-+ linking a base relative executable. */
-+ for (ld1=ld1_argv; *ld1; ld1++)
-+ {
-+ int len=strlen(*ld1);
-+ if (strncmp(*ld1, "-l", strlen("-l"))==0)
-+ {
-+ for (lib=head; lib; lib=lib->next)
-+ if (strcmp(*ld1+strlen("-l"), lib->name)==0)
-+ {
-+ char *newname=(char*)
-+ xmalloc(strlen(*ld1)+strlen(DYNAMIC_LIB_SUFFIX)+1);
-+ strcpy(newname, *ld1);
-+ strcat(newname, DYNAMIC_LIB_SUFFIX);
-+ *ld1=newname;
-+ break;
-+ }
-+ }
-+ else if (len > 2 && !strcmp(*ld1 + len - 2, ".a"))
-+ {
-+ const char *libname;
-+ int substituted=0;
-+
-+ ((char *)(*ld1))[len - 2] = '\0';
-+ libname = strrchr(*ld1, '/');
-+ if (libname == NULL)
-+ libname = strrchr(*ld1, ':');
-+ if (libname == NULL)
-+ libname = *ld1 - 1;
-+ if (!strncmp(libname + 1, "lib", 3))
-+ for (lib=head; lib; lib=lib->next)
-+ if (strcmp(libname+4, lib->name)==0)
-+ {
-+ char *newname=(char*)xmalloc(strlen(*ld1)+
-+ strlen(DYNAMIC_LIB_SUFFIX)+3);
-+ strcpy(newname, *ld1);
-+ strcat(newname, DYNAMIC_LIB_SUFFIX);
-+ strcat(newname, ".a");
-+ *ld1=newname;
-+ substituted=1;
-+ break;
-+ }
-+ if (!substituted)
-+ ((char *)(*ld1))[len - 2] = '.';
-+ }
-+ else if (strcmp(ld1[0], "-m")==0 && ld1[1]
-+ && strcmp(ld1[1], "amiga_bss")==0)
-+ {
-+ flag_baserel=1;
-+ break;
-+ }
-+ }
-+
-+ out = fopen(XLIBS_C_NAME, "w");
-+ if (out == NULL)
-+ fatal_error (input_location, "%s", XLIBS_C_NAME);
-+ x = fopen(SHARED_X_NAME, "w");
-+ if (x == NULL)
-+ fatal_error (input_location, "%s", SHARED_X_NAME);
-+
-+ cat((flag_baserel ? A2IXDIR_PREFIX "/amiga_exe_baserel_script.x"
-+ : A2IXDIR_PREFIX "/amiga_exe_script.x"), x);
-+ for (lib = head; lib; lib = lib->next)
-+ {
-+ static char buf[256];
-+ sprintf(buf, A2IXDIR_PREFIX "/ldscripts/%s.x", lib->name);
-+ fprintf(out, "extern long %sBase; long *__p%sBase = &%sBase;\n",
-+ lib->cname, lib->cname, lib->cname);
-+ cat(buf, x);
-+ } /* {{ */
-+ fprintf(x, "}}\n");
-+ fclose(out);
-+ fclose(x);
-+ argv[0]=c_file_name;
-+ fork_execute("gcc", (char **)argv, false);
-+
-+ /* Unfortunately, unlike "-s", "-T" cannot be specified as the
last
-+ argument. We put it after "-L" args. */
-+ ld1_end=ld1_argv;
-+ while (*ld1_end)
-+ ld1_end++;
-+ ld1_end++;
-+ /* "ld1_end" now points after the terminating 0 of "ld1_argv".
*/
-+
-+ ld1=ld1_end-2;
-+ while (ld1>ld1_argv && strncmp(*ld1, "-L",
strlen("-L")))
-+ ld1--;
-+ if (ld1==ld1_argv)
-+ fatal_error (input_location, "no -L arguments");
-+ ld1++;
-+ /* "ld1" now points after "-L". */
-+
-+ /* Shift all the arguments after "-L" one position right. */
-+ memmove(ld1+1, ld1, (ld1_end-ld1)*sizeof(*ld1));
-+ /* Put -Tshared.x in the now empty space. */
-+ *ld1="-T" SHARED_X_NAME;
-+ }
-+}
-+
-+/* Be lazy and just call "postlink". */
-+
-+void
-+amigaos_postlink_hook (const char *output_file)
-+{
-+ static const char *argv[]={"postlink", 0, 0, 0};
-+ if (flag_static)
-+ return;
-+
-+ if (flag_baserel)
-+ {
-+ argv[1]="-baserel";
-+ argv[2]=output_file;
-+ }
-+ else
-+ argv[1]=output_file;
-+ fork_execute("postlink", (char **)argv, false);
-+}
-diff --git a/gcc/bbb-opts.c b/gcc/bbb-opts.c
-new file mode 100755
-index 000000000000..9e989e9b1ec0
---- /dev/null
-+++ gcc/bbb-opts.c
-@@ -0,0 +1,4705 @@
-+/* Bebbo's Optimizations.
-+ Copyright (C) 2010-2017 Free Software Foundation, Inc.
-+ Copyright (C) 2017 Stefan "Bebbo" Franke.
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify it under
-+ the terms of the GNU General Public License as published by the Free
-+ Software Foundation; either version 3, or (at your option) any later
-+ version.
-+
-+ GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+ WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+ for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING3. If not see
-+ <
http://www.gnu.org/licenses/>. */
-+
-+/**
-+ * SBF (Stefan "Bebbo" Franke):
-+ *
-+ * This pass performs multiple optimizations.
-+ *
-+ * #1 propagate_moves
-+ * check if a->b->a can be moved out of a loop.
-+ *
-+ * #2 strcpy
-+ * check if a temp reg can be eliminated.
-+ *
-+ * #3 const_comp_sub
-+ * convert a compare with int constant into sub statement.
-+ *
-+ * #4 merge_add
-+ * merge adds
-+ *
-+ * #5 elim_dead_assign
-+ * eliminate some dead assignments.
-+ *
-+ * #6 shrink stack frame
-+ * remove push/pop for unused variables
-+ *
-+ * #7 rename register
-+ * rename registers without breaking register parameters, inline asm etc.
-+ *
-+ * Lessons learned:
-+ *
-+ * - do not trust existing code, better delete insns and inster a new one.
-+ * - do not modify insns, create new insns from pattern
-+ * - do not reuse registers, create new reg rtx instances
-+ *
-+ */
-+
-+#include "config.h"
-+#define INCLUDE_VECTOR
-+#define INCLUDE_SET
-+#define INCLUDE_MAP
-+#include "system.h"
-+#include "coretypes.h"
-+#include "backend.h"
-+#include "target.h"
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "insn-config.h"
-+#include "recog.h"
-+#include "cfgrtl.h"
-+#include "emit-rtl.h"
-+#include "tree.h"
-+#include "tree-pass.h"
-+#include "conditions.h"
-+#include "langhooks.h"
-+#include <vector>
-+#include <set>
-+#include <map>
-+
-+int be_very_verbose;
-+bool be_verbose;
-+
-+extern struct lang_hooks lang_hooks;
-+
-+static void
-+update_insn_infos (void);
-+static unsigned
-+track_regs ();
-+
-+/* Lookup of the current function name. */
-+extern tree current_function_decl;
-+static tree last_function_decl;
-+static char fxname[512];
-+static char const *
-+get_current_function_name ()
-+{
-+ if (current_function_decl == NULL)
-+ strcpy (fxname, "<toplevel>");
-+ else
-+ strcpy (fxname, lang_hooks.decl_printable_name (current_function_decl, 2));
-+ return fxname;
-+}
-+
-+/* a simple log to stdout. */
-+static int
-+log (char const * fmt, ...)
-+{
-+ if (!be_verbose)
-+ return 0;
-+
-+ va_list args;
-+ va_start(args, fmt);
-+ if (last_function_decl != current_function_decl)
-+ {
-+ last_function_decl = current_function_decl;
-+ printf (":bbb: in '%s'\n", get_current_function_name ());
-+ }
-+ printf (":bbb: ");
-+ int retval = vprintf (fmt, args);
-+ va_end(args);
-+ fflush (stdout);
-+ return retval;
-+}
-+
-+enum proepis
-+{
-+ IN_CODE, IN_PROLOGUE, IN_EPILOGUE, IN_EPILOGUE_PARALLEL_POP
-+};
-+
-+/**
-+ * What's needed to track values?
-+ */
-+class track_var
-+{
-+ rtx value[FIRST_PSEUDO_REGISTER];
-+ unsigned mask[FIRST_PSEUDO_REGISTER];
-+
-+ bool
-+ extend (rtx * z, unsigned * mask, machine_mode dstMode, rtx x)
-+ {
-+ switch (GET_CODE(x))
-+ {
-+ case CONST_INT:
-+ case CONST_FIXED:
-+ case CONST_DOUBLE:
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ {
-+ rtx v = value[REGNO(x)];
-+ unsigned mr = mask[REGNO(x)];
-+ /* try to expand the register. */
-+ if (v)
-+ {
-+ if (dstMode != GET_MODE(v) && (GET_CODE(v) != CONST_INT || mr == (1
<< FIRST_PSEUDO_REGISTER)))
-+ return false;
-+
-+ *mask |= mr;
-+ *z = v;
-+ return true;
-+ }
-+
-+ /* store the reg otherwise. */
-+ *mask |= (1 << REGNO(x));
-+ if (GET_MODE(x) == dstMode)
-+ *z = x;
-+ else
-+ *z = gen_rtx_REG (dstMode, REGNO(x));
-+ return true;
-+ }
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(x, 0);
-+ if (GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF &&
amiga_is_const_pic_ref (y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant
offset (later).
-+ *z = gen_rtx_PLUS(GET_MODE(x), y, XEXP(x, 1));
-+ else
-+ *z = gen_rtx_MINUS(GET_MODE(x), y, XEXP(x, 1));
-+ return true;
-+ }
-+
-+ /* memory reads. */
-+ case MEM:
-+ {
-+ rtx m = XEXP(x, 0);
-+ switch (GET_CODE(m))
-+ {
-+ case SYMBOL_REF:
-+ case LABEL_REF:
-+ /* these can be used directly. */
-+ *z = x;
-+ return true;
-+
-+ case REG:
-+ if (!extend (&m, mask, dstMode, m))
-+ return false;
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+
-+ case PLUS:
-+ case MINUS:
-+ // handle only in combination with const
-+ {
-+ rtx y = XEXP(m, 0);
-+ if (!REG_P(y) && GET_CODE(y) != SYMBOL_REF && GET_CODE(y) == LABEL_REF
&& amiga_is_const_pic_ref (y))
-+ return false;
-+
-+ if (REG_P(y))
-+ if (!extend (&y, mask, dstMode, y))
-+ return false;
-+
-+ if (GET_CODE(x) == PLUS) // create an own plus to be able to modify the constant
offset (later).
-+ m = gen_rtx_PLUS(GET_MODE(m), y, XEXP(m, 1));
-+ else
-+ m = gen_rtx_MINUS(GET_MODE(m), y, XEXP(m, 1));
-+
-+ *z = gen_rtx_MEM (GET_MODE(x), m);
-+ return true;
-+ }
-+ default:
-+ return false;
-+ }
-+ break;
-+ }
-+ default:
-+ return false;
-+ }
-+ }
-+
-+public:
-+ track_var (track_var const * o = 0)
-+ {
-+ if (o)
-+ assign (o);
-+ else
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+
-+ int
-+ find_alias (rtx src)
-+ {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend (&z, &m, GET_MODE(src), src))
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ // do not alias small int value from -128 ... 127
-+ if (rtx_equal_p (z, value[i]) && (GET_CODE(z) != CONST_INT || INTVAL(z)
> 127 || INTVAL(z) < -128))
-+ return i;
-+ }
-+ }
-+ return -1;
-+ }
-+ void
-+ invalidate_mem (rtx dst)
-+ {
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (extend (&z, &m, GET_MODE(dst), dst))
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (rtx_equal_p (z, value[i]))
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ }
-+ }
-+
-+ rtx
-+ get (unsigned regno)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return 0;
-+
-+ return value[regno];
-+ }
-+
-+ void
-+ set (machine_mode mode, unsigned regno, rtx x, unsigned index)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return;
-+
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+
-+ if (!extend (&value[regno], &mask[regno], mode, x))
-+ {
-+ clear (mode, regno, index);
-+ }
-+ }
-+
-+ bool
-+ equals (unsigned regno, rtx x)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return false;
-+
-+ if (x == 0 || value[regno] == 0)
-+ return false;
-+
-+ rtx z = 0;
-+ unsigned m = 0;
-+ if (!extend (&z, &m, GET_MODE(x), x))
-+ return false;
-+
-+ return rtx_equal_p (z, value[regno]);
-+ }
-+
-+ void
-+ clear (machine_mode mode, unsigned regno, unsigned index)
-+ {
-+ if (regno >= FIRST_PSEUDO_REGISTER)
-+ return;
-+
-+ if (mode == SFmode && regno < 16)
-+ mode = SImode;
-+ value[regno] = gen_rtx_raw_CONST_INT(mode, 0x100000000000000LL | ((long long int )
(regno) << 32) | index);
-+ mask[regno] = 1 << FIRST_PSEUDO_REGISTER;
-+ }
-+
-+ void
-+ clear_aftercall (unsigned index)
-+ {
-+ for (int i = 2; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (mask[i] && mask[i] < 1 << FIRST_PSEUDO_REGISTER)
-+ {
-+ value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ clear (SImode, 0, index);
-+ clear (SImode, 1, index);
-+ clear (SImode, 8, index);
-+ clear (SImode, 9, index);
-+ }
-+
-+ void
-+ clear_for_mask (unsigned def, unsigned index)
-+ {
-+ if (!def)
-+ return;
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ // register changed or used somehow
-+ if ((1 << regno) & def)
-+ clear (SImode, regno, index);
-+ }
-+ }
-+
-+ void
-+ assign (track_var const * o)
-+ {
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ value[i] = o->value[i];
-+ mask[i] = o->mask[i];
-+ }
-+ }
-+
-+ /* only keep common values in both sides. */
-+ void
-+ merge (track_var * o, unsigned)
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ {
-+ value[i] = o->value[i] = 0;
-+ mask[i] = 0;
-+ }
-+ }
-+ }
-+
-+ /* true if a merge would not change anything. */
-+ bool
-+ no_merge_needed (track_var const * o) const
-+ {
-+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ {
-+ if (!rtx_equal_p (value[i], o->value[i]))
-+ return false;
-+ }
-+ return true;
-+ }
-+};
-+
-+/* Information for each insn to detect alive registers. Enough for m68k.
-+ * Why a class? Maybe extend it for general usage.
-+ *
-+ * Track use & def separate to determine starting points.
-+ */
-+class insn_info
-+{
-+ rtx_insn * insn; // the insn
-+
-+// usage flags
-+ unsigned myuse; // bit set if registers are used in this statement
-+ unsigned hard; // bit set if registers can't be renamed
-+ unsigned use; // bit set if registers are used in program flow
-+ unsigned def; // bit set if registers are defined here
-+
-+ enum proepis proepi;
-+
-+ bool stack; // part of stack frame insns
-+
-+// stuff to analyze insns
-+ bool label;
-+ bool jump;
-+ bool call;
-+ bool compare;
-+ bool dst_mem;
-+ bool src_mem;
-+ bool dst_plus;
-+ bool src_plus;
-+ rtx_code src_op;
-+ bool src_ee;
-+ bool src_2nd;
-+ bool src_const;
-+
-+ machine_mode mode;
-+
-+ rtx dst_reg;
-+ rtx dst_mem_reg;
-+ rtx dst_symbol;
-+ rtx src_reg;
-+ rtx src_mem_reg;
-+ rtx src_symbol;
-+ unsigned dst_mem_addr;
-+ int src_intval;
-+ unsigned src_mem_addr;
-+
-+ bool visited;
-+
-+ int sp_offset;
-+
-+ int dst_autoinc;
-+ int src_autoinc;
-+
-+// values for all variables - if used
-+ track_var * track;
-+
-+public:
-+ insn_info (rtx_insn * i = 0, enum proepis p = IN_CODE) :
-+ insn (i), myuse (0), hard (0), use (0), def (0), proepi (p), stack (false), label
(false), jump (false), call (
-+ false), compare (false), dst_mem (false), src_mem (false), dst_plus (false), src_plus
(false), src_op (
-+ (rtx_code) 0), src_ee (false), src_2nd (false), src_const (false), mode (VOIDmode),
dst_reg (0), dst_mem_reg (
-+ 0), dst_symbol (0), src_reg (0), src_mem_reg (0), src_symbol (0), dst_mem_addr (0),
src_intval (0), src_mem_addr (
-+ 0), visited (false), sp_offset (0), dst_autoinc (0), src_autoinc (0), track (0)
-+ {
-+ }
-+
-+ track_var *
-+ get_track_var ();
-+
-+ inline ptrdiff_t
-+ operator < (insn_info const & o) const
-+ {
-+ return this - &o;
-+ }
-+
-+ int
-+ get_index () const;
-+
-+ void
-+ plus_to_move (rtx_insn * newinsn);
-+
-+ void
-+ swap_adds (rtx_insn * newinsn, insn_info & ii);
-+
-+ void
-+ absolute2base (unsigned regno, unsigned base, rtx with_symbol);
-+
-+ rtx
-+ make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool apply);
-+
-+ inline bool
-+ is_compare () const
-+ {
-+ return compare;
-+ }
-+
-+ inline machine_mode
-+ get_mode () const
-+ {
-+ return mode;
-+ }
-+
-+ inline bool
-+ is_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
-+
-+ inline bool
-+ is_dst_mem () const
-+ {
-+ return dst_mem;
-+ }
-+
-+ inline bool
-+ is_src_mem () const
-+ {
-+ return src_mem;
-+ }
-+
-+ inline bool
-+ is_src_mem_2nd () const
-+ {
-+ return src_2nd && src_mem;
-+ }
-+
-+ inline bool
-+ has_dst_memreg () const
-+ {
-+ return dst_mem_reg;
-+ }
-+
-+ inline bool
-+ has_src_memreg () const
-+ {
-+ return src_mem_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_symbol () const
-+ {
-+ return dst_symbol;
-+ }
-+
-+ inline rtx
-+ get_src_symbol () const
-+ {
-+ return src_symbol;
-+ }
-+ inline bool
-+ has_dst_addr () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline bool
-+ has_src_addr () const
-+ {
-+ return src_mem_addr;
-+ }
-+
-+ inline bool
-+ is_label () const
-+ {
-+ return label;
-+ }
-+
-+ inline bool
-+ is_jump () const
-+ {
-+ return jump;
-+ }
-+
-+ inline bool
-+ is_call () const
-+ {
-+ return call;
-+ }
-+
-+ inline unsigned
-+ get_dst_mem_addr () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline unsigned
-+ get_src_mem_addr () const
-+ {
-+ return src_mem_addr;
-+ }
-+
-+ inline bool
-+ is_src_reg () const
-+ {
-+ return src_reg && !src_op;
-+ }
-+
-+ inline int
-+ get_src_op () const
-+ {
-+ return src_op;
-+ }
-+
-+ inline bool
-+ is_src_ee () const
-+ {
-+ return src_ee;
-+ }
-+
-+ inline bool
-+ is_src_mem_plus () const
-+ {
-+ return src_mem && src_plus;
-+ }
-+
-+ inline bool
-+ is_dst_mem_plus () const
-+ {
-+ return dst_mem && dst_plus;
-+ }
-+
-+ inline int
-+ get_dst_regno () const
-+ {
-+ return dst_reg ? REGNO(dst_reg) : -1;
-+ }
-+
-+ inline int
-+ get_src_regno () const
-+ {
-+ return src_reg ? REGNO(src_reg) : -1;
-+ }
-+
-+ inline rtx
-+ get_src_reg () const
-+ {
-+ return src_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_reg () const
-+ {
-+ return dst_reg;
-+ }
-+
-+ inline int
-+ get_src_mem_regno () const
-+ {
-+ return src_mem_reg ? REGNO(src_mem_reg) : -1;
-+ }
-+
-+ inline int
-+ get_dst_mem_regno () const
-+ {
-+ return dst_mem_reg ? REGNO(dst_mem_reg) : -1;
-+ }
-+
-+ inline rtx
-+ get_src_mem_reg () const
-+ {
-+ return src_mem_reg;
-+ }
-+
-+ inline rtx
-+ get_dst_mem_reg () const
-+ {
-+ return dst_mem_reg;
-+ }
-+
-+ inline int
-+ get_src_intval () const
-+ {
-+ return src_intval;
-+ }
-+
-+ inline int
-+ get_dst_intval () const
-+ {
-+ return dst_mem_addr;
-+ }
-+
-+ inline bool
-+ is_src_const () const
-+ {
-+ return src_const;
-+ }
-+
-+ inline void
-+ mark_jump ()
-+ {
-+ jump = true;
-+ }
-+ inline void
-+ mark_call ()
-+ {
-+ call = true;
-+ }
-+ inline void
-+ mark_label ()
-+ {
-+ label = true;
-+ }
-+
-+ void
-+ fledder (rtx set);
-+
-+ void
-+ fledder_src_mem (rtx src);
-+
-+ /* update usage. */
-+ void
-+ update (insn_info & o)
-+ {
-+ myuse = o.myuse;
-+ hard = o.hard;
-+ use = o.use;
-+ def = o.def;
-+ }
-+
-+ inline rtx_insn *
-+ get_insn () const
-+ {
-+ return insn;
-+ }
-+
-+ void
-+ mark_stack ()
-+ {
-+ stack = true;
-+ }
-+
-+ bool
-+ is_stack () const
-+ {
-+ return stack;
-+ }
-+
-+ inline enum proepis
-+ in_proepi () const
-+ {
-+ return proepi;
-+ }
-+
-+ inline void
-+ set_proepi (enum proepis p)
-+ {
-+ proepi = p;
-+ }
-+
-+ inline void
-+ reset_flags ()
-+ {
-+ label = false;
-+ jump = false;
-+ compare = false;
-+ dst_mem = false;
-+ src_mem = false;
-+ dst_plus = false;
-+ src_plus = false;
-+ src_op = (rtx_code) 0;
-+ src_ee = false;
-+ src_const = false;
-+
-+ mode = VOIDmode;
-+
-+ dst_reg = 0;
-+ dst_mem_reg = 0;
-+ dst_symbol = 0;
-+ src_reg = 0;
-+ src_mem_reg = 0;
-+ src_symbol = 0;
-+ dst_mem_addr = 0;
-+
-+ src_intval = 0;
-+ src_mem_addr = 0;
-+
-+ dst_autoinc = 0;
-+ src_autoinc = 0;
-+ }
-+
-+ inline int
-+ get_src_autoinc () const
-+ {
-+ return src_autoinc;
-+ }
-+
-+ inline int
-+ get_dst_autoinc () const
-+ {
-+ return dst_autoinc;
-+ }
-+
-+ inline bool
-+ is_empty ()
-+ {
-+ return !def && !use && !hard;
-+ }
-+
-+ inline void
-+ mark_myuse (int regno)
-+ {
-+ myuse |= 1 << regno;
-+ use |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_use (int regno)
-+ {
-+ use |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_def (int regno)
-+ {
-+ def |= 1 << regno;
-+ }
-+
-+ inline void
-+ mark_hard (int regno)
-+ {
-+ hard |= 1 << regno;
-+ }
-+
-+ inline void
-+ unset (int regno)
-+ {
-+ use &= ~(1 << regno);
-+ def &= ~(1 << regno);
-+ hard &= ~(1 << regno);
-+ }
-+
-+ inline unsigned
-+ get_use () const
-+ {
-+ return use;
-+ }
-+
-+ inline unsigned
-+ get_myuse () const
-+ {
-+ return myuse;
-+ }
-+
-+ inline void
-+ set_use (unsigned u)
-+ {
-+ use = u;
-+ }
-+
-+ inline unsigned
-+ get_def () const
-+ {
-+ return def;
-+ }
-+ inline unsigned
-+ get_hard () const
-+ {
-+ return hard;
-+ }
-+
-+ inline bool
-+ is_use (int regno)
-+ {
-+ return (use & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_myuse (int regno)
-+ {
-+ return (myuse & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_def (int regno)
-+ {
-+ return (def & (1 << regno)) != 0;
-+ }
-+
-+ inline bool
-+ is_hard (int regno)
-+ {
-+ return (hard & (1 << regno)) != 0;
-+ }
-+
-+ inline void
-+ clear_hard_def ()
-+ {
-+ hard = 0;
-+ def = 0;
-+ }
-+
-+ /*
-+ * update for previous insn.
-+ * - remove regs which are defined here
-+ * - add regs which are used here
-+ * - reset _def
-+ * - restrain _hard to used
-+ */
-+ inline void
-+ updateWith (insn_info const & o)
-+ {
-+ use &= ~o.def;
-+ use |= o.use;
-+ def = 0;
-+ }
-+
-+ inline insn_info &
-+ merge (insn_info const & o)
-+ {
-+ myuse = o.myuse;
-+ use = (use & ~o.def) | o.use;
-+ def |= o.def;
-+ hard |= o.hard;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ or_use (insn_info const & o)
-+ {
-+ use |= o.myuse | o.def | o.hard;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ drop_def ()
-+ {
-+ use &= ~def;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ make_hard ()
-+ {
-+ hard = use | def;
-+ return *this;
-+ }
-+
-+ inline insn_info &
-+ make_clobber ()
-+ {
-+ hard = use = def = use | def;
-+ return *this;
-+ }
-+
-+ inline bool
-+ contains (insn_info const & o) const
-+ {
-+ if (o.def & ~def)
-+ return false;
-+ if (o.use & ~use)
-+ return false;
-+ if (o.hard & ~hard)
-+ return false;
-+ return true;
-+ }
-+
-+ inline int
-+ get_sp_offset () const
-+ {
-+ return sp_offset;
-+ }
-+
-+ inline void
-+ set_sp_offset (int sp)
-+ {
-+ sp_offset = sp;
-+ }
-+
-+ inline bool
-+ is_visited () const
-+ {
-+ return visited;
-+ }
-+
-+ inline void
-+ mark_visited ()
-+ {
-+ visited = true;
-+ }
-+
-+ inline void
-+ clear_visited ()
-+ {
-+ visited = false;
-+ }
-+
-+ void
-+ scan ();
-+
-+ void
-+ scan_rtx (rtx);
-+
-+ bool
-+ make_post_inc (int regno);
-+
-+ void
-+ auto_inc_fixup (int regno, int size);
-+
-+ /* return bits for alternate free registers. */
-+ unsigned
-+ get_free_mask () const
-+ {
-+ if (def & hard)
-+ return 0;
-+
-+ if (!def)
-+ return 0;
-+
-+ unsigned def_no_cc = def & ~(1 << FIRST_PSEUDO_REGISTER);
-+ if (def_no_cc > 0x4000)
-+ return 0;
-+
-+ unsigned mask = def_no_cc - 1;
-+ /* more than one register -> don't touch. */
-+ if ((mask & ~def) != mask)
-+ return 0;
-+
-+ if (def_no_cc > 0xff)
-+ mask &= 0xff00;
-+
-+ return mask & ~use;
-+ }
-+
-+ unsigned
-+ get_regbit () const
-+ {
-+ if (GET_MODE_SIZE(mode) > 4)
-+ return 0;
-+ return def & ~hard & ~use & 0x7fff;
-+ }
-+
-+ void
-+ set_insn (rtx_insn * newinsn);
-+
-+ void
-+ a5_to_a7 (rtx a7);
-+};
-+
-+bool
-+insn_info::make_post_inc (int regno)
-+{
-+ rtx pattern = PATTERN (insn);
-+ rtx_insn * new_insn = make_insn_raw (pattern);
-+
-+ // convert into POST_INC
-+ rtx set0 = single_set (new_insn);
-+ if (!set0)
-+ return false;
-+
-+ rtx set = set0;
-+
-+ if (is_compare ())
-+ set = SET_SRC(set);
-+ rtx mem = get_dst_mem_regno () == regno ? SET_DEST(set) : SET_SRC(set);
-+
-+ if (src_op && get_src_mem_regno () == regno)
-+ {
-+ if (src_op == NEG || src_op == NOT || src_op == SIGN_EXTEND)
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-+
-+ rtx reg = XEXP(mem, 0);
-+
-+ XEXP(mem, 0) = gen_rtx_POST_INC(SImode, reg);
-+
-+ if (insn_invalid_p (new_insn, 0))
-+ {
-+ XEXP(mem, 0) = reg;
-+ insn_invalid_p (insn, 0);
-+ return 0;
-+ }
-+
-+ SET_INSN_DELETED(insn);
-+ (get_dst_mem_regno () == regno ? dst_autoinc : src_autoinc) = GET_MODE_SIZE(mode);
-+ insn = emit_insn_after (PATTERN (new_insn), insn);
-+ insn_invalid_p (insn, 0);
-+
-+ return 1;
-+}
-+
-+static rtx
-+add_clobbers (rtx_insn * oldinsn)
-+{
-+ rtx pattern = PATTERN (oldinsn);
-+ if (GET_CODE(pattern) != PARALLEL)
-+ return pattern;
-+
-+ int num_clobbers = 0;
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ ++num_clobbers;
-+ }
-+
-+ if (!num_clobbers)
-+ return pattern;
-+
-+ rtx newpat = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (num_clobbers + 1));
-+ for (int j = XVECLEN (pattern, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(x) == CLOBBER)
-+ XVECEXP(newpat, 0, num_clobbers--) = x;
-+ }
-+
-+ XVECEXP(newpat, 0, 0) = XVECEXP(pattern, 0, 0);
-+ return newpat;
-+}
-+
-+void
-+insn_info::auto_inc_fixup (int regno, int size)
-+{
-+// debug_rtx (insn);
-+ rtx set0 = single_set (insn);
-+ rtx set = set0;
-+ if (is_compare ())
-+ set = SET_SRC(set);
-+
-+ // add to register
-+ if (get_src_regno () == regno)
-+ {
-+ rtx src = SET_SRC(set);
-+ if (get_src_intval () == size)
-+ {
-+ src_intval = 0;
-+ src_plus = false;
-+ SET_SRC(set) = XEXP(src, 0);
-+ }
-+ else
-+ XEXP(src, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(src, 1)), src_intval -= size);
-+ }
-+ else if (get_src_mem_regno () == regno)
-+ {
-+ // src mem used ?
-+ rtx mem = SET_SRC(set);
-+ if (src_op)
-+ {
-+ if (MEM_P(XEXP(mem, 0)))
-+ mem = XEXP(mem, 0);
-+ else
-+ mem = XEXP(mem, 1);
-+ }
-+ rtx plus = XEXP(mem, 0);
-+
-+ if (src_mem_addr == (unsigned) size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ src_mem_addr = 0;
-+ src_plus = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), src_mem_addr -= size);
-+ }
-+
-+ if (get_dst_mem_regno () == regno)
-+ {
-+ rtx mem = SET_DEST(set);
-+ rtx plus = XEXP(mem, 0);
-+ if (dst_mem_addr == (unsigned) size)
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ dst_mem_addr = 0;
-+ dst_plus = false;
-+ }
-+ else
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (GET_MODE(XEXP(plus, 1)), dst_mem_addr -= size);
-+ }
-+
-+ rtx pattern = add_clobbers (insn);
-+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
-+}
-+
-+track_var *
-+insn_info::get_track_var ()
-+{
-+ if (!track)
-+ track = new track_var ();
-+ return track;
-+}
-+
-+void
-+insn_info::scan ()
-+{
-+ rtx pattern = PATTERN (insn);
-+ if (ANY_RETURN_P(pattern))
-+ {
-+ tree type = TYPE_SIZE(TREE_TYPE (DECL_RESULT (current_function_decl)));
-+ int sz = type ? TREE_INT_CST_LOW(type) : 0;
-+ // log ("return size %d\n", sz);
-+ if (sz <= 64)
-+ {
-+ mark_hard (0);
-+ mark_myuse (0);
-+ if (sz > 32)
-+ {
-+ mark_hard (1);
-+ mark_myuse (1);
-+ }
-+ }
-+ }
-+ else if (CALL_P(insn))
-+ {
-+ /* add mregparm registers. */
-+ for (rtx link = CALL_INSN_FUNCTION_USAGE(insn); link; link = XEXP(link, 1))
-+ {
-+ rtx op, reg;
-+
-+ if (GET_CODE (op = XEXP (link, 0)) == USE && REG_P(reg = XEXP (op, 0)))
-+ for (unsigned r = REGNO(reg); r < END_REGNO (reg); ++r)
-+ mark_myuse (r);
-+ }
-+ /* mark scratch registers. */
-+ mark_def (0);
-+ mark_def (1);
-+ mark_def (8);
-+ mark_def (9);
-+ /* also mark all registers as not renamable */
-+ hard = use;
-+ }
-+ scan_rtx (pattern);
-+}
-+
-+/* scan rtx for registers and set the corresponding flags. */
-+void
-+insn_info::scan_rtx (rtx x)
-+{
-+ if (REG_P(x))
-+ {
-+ for (int n = REG_NREGS(x), r = REGNO(x); n > 0; --n, ++r)
-+ mark_myuse (r);
-+ return;
-+ }
-+
-+ if (x == cc0_rtx)
-+ {
-+ mark_myuse (FIRST_PSEUDO_REGISTER);
-+ return;
-+ }
-+
-+ RTX_CODE code = GET_CODE(x);
-+
-+ /* handle SET and record use and def. */
-+ if (code == SET)
-+ {
-+ unsigned u = use;
-+ unsigned mu = myuse;
-+ use = myuse = 0;
-+ rtx dst = SET_DEST(x);
-+ scan_rtx (dst);
-+ if (REG_P(dst) || ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
&& REG_P(XEXP(dst, 0))))
-+ {
-+ def |= use;
-+ if ((GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG))
-+ use |= u;
-+ else
-+ use = u;
-+ myuse = mu;
-+ }
-+
-+ // avoid side effects from myuse -> def, e.g. adding the dst reg to def by src
auto inc
-+ mu = myuse;
-+ myuse = 0;
-+ scan_rtx (SET_SRC(x));
-+ myuse |= mu;
-+
-+ int code = GET_CODE(SET_SRC(x));
-+ if (code == ASM_OPERANDS)
-+ hard |= def | use;
-+ return;
-+ }
-+
-+ if (code == TRAP_IF)
-+ {
-+ /* mark all registers used. */
-+ hard = use = myuse = (1 << FIRST_PSEUDO_REGISTER) - 1;
-+ return;
-+ }
-+
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ scan_rtx (XEXP(x, i));
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ {
-+ unsigned u = use;
-+ unsigned mu = myuse;
-+ unsigned d = def;
-+ scan_rtx (XVECEXP(x, i, j));
-+ use |= u;
-+ myuse |= mu;
-+ def |= d;
-+ }
-+ }
-+
-+ if (code == POST_INC || code == PRE_DEC || code == CLOBBER)
-+ def |= myuse;
-+}
-+
-+void
-+insn_info::fledder_src_mem (rtx src)
-+{
-+ src_mem = true;
-+ rtx mem = XEXP(src, 0);
-+
-+ if (GET_CODE(mem) == POST_INC)
-+ src_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ src_autoinc = -1, mem = XEXP(mem, 0);
-+
-+ if (REG_P(mem))
-+ src_mem_reg = mem;
-+ else if (GET_CODE(mem) == CONST_INT)
-+ src_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ src_symbol = mem;
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ src_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ src_mem_reg = reg;
-+ src_const = true;
-+ src_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ src_plus = true;
-+ src_symbol = sym;
-+ src_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
-+}
-+
-+/* read the set and grab infos */
-+void
-+insn_info::fledder (rtx set)
-+{
-+ if (!set || GET_CODE(set) == PARALLEL)
-+ return;
-+
-+ rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
-+
-+ if (dst == cc0_rtx)
-+ {
-+ compare = true;
-+ set = src;
-+ dst = SET_DEST(set);
-+ src = SET_SRC(set);
-+ }
-+
-+ if (GET_CODE(dst) == STRICT_LOW_PART || GET_CODE(dst) == SUBREG)
-+ dst = XEXP(dst, 0);
-+
-+ mode = GET_MODE(dst);
-+ if (mode == VOIDmode)
-+ mode = GET_MODE(src);
-+
-+ if (REG_P(dst))
-+ {
-+ dst_reg = dst;
-+ }
-+ else if (MEM_P(dst))
-+ {
-+ dst_mem = true;
-+ rtx mem = XEXP(dst, 0);
-+
-+ if (GET_CODE(mem) == POST_INC)
-+ dst_autoinc = 1, mem = XEXP(mem, 0);
-+ else if (GET_CODE(mem) == PRE_DEC)
-+ dst_autoinc = -1, mem = XEXP(mem, 0);
-+
-+ if (REG_P(mem))
-+ dst_mem_reg = mem;
-+ else if (GET_CODE(mem) == CONST_INT)
-+ dst_mem_addr = INTVAL(mem);
-+ else if (GET_CODE(mem) == SYMBOL_REF)
-+ dst_symbol = mem;
-+ else if (GET_CODE(mem) == PLUS)
-+ {
-+ dst_plus = true;
-+ rtx reg = XEXP(mem, 0);
-+ rtx konst = XEXP(mem, 1);
-+ if (REG_P(reg) && GET_CODE(konst) == CONST_INT)
-+ {
-+ dst_mem_reg = reg;
-+ dst_mem_addr = INTVAL(konst);
-+ }
-+ }
-+ else if (GET_CODE(mem) == CONST)
-+ {
-+ mem = XEXP(mem, 0);
-+ if (GET_CODE(mem) == PLUS)
-+ {
-+ rtx sym = XEXP(mem, 0);
-+ if (GET_CODE(sym) == SYMBOL_REF)
-+ {
-+ dst_plus = true;
-+ dst_symbol = sym;
-+ dst_mem_addr = INTVAL(XEXP(mem, 1));
-+ }
-+ }
-+ }
-+ }
-+
-+ /* It' some kind of operation, e.g. PLUS, XOR, NEG, ... */
-+ rtx alt_src_reg = 0;
-+ int code = GET_CODE(src);
-+ if (!REG_P(src) && !MEM_P(src) && code != CONST_INT && code !=
CONST && code != CONST_WIDE_INT && code != CONST_DOUBLE
-+ && code != CONST_FIXED && code != CONST_STRING)
-+ {
-+ src_op = GET_CODE(src);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ if (fmt[0] == 'e' && fmt[1] == 'e')
-+ {
-+ src_ee = true;
-+ rtx operand = XEXP(src, 1);
-+ if (GET_CODE(operand) == CONST_INT || GET_CODE(operand) == CONST_WIDE_INT)
-+ src_const = true, src_intval = INTVAL(operand);
-+ else if (REG_P(operand))
-+ {
-+ alt_src_reg = operand;
-+ }
-+ else if (MEM_P(operand))
-+ {
-+ // it' something like reg = op(reg, mem(...))
-+ src_2nd = true;
-+ fledder_src_mem (operand);
-+ }
-+ }
-+ src = XEXP(src, 0);
-+ }
-+
-+ if (REG_P(src))
-+ {
-+ src_reg = src;
-+ }
-+ else if (MEM_P(src))
-+ {
-+ fledder_src_mem (src);
-+ }
-+ else if (GET_CODE(src) == CONST_INT)
-+ {
-+ src_const = true;
-+ src_intval = INTVAL(src);
-+ }
-+ if (alt_src_reg)
-+ src_reg = alt_src_reg;
-+}
-+
-+/* create a copy for a reg. Optional specify a new register number. */
-+static rtx
-+copy_reg (rtx reg, int newregno)
-+{
-+ if (newregno < 0)
-+ newregno = REGNO(reg);
-+ rtx x = gen_raw_REG (GET_MODE(reg), newregno);
-+ x->jump = reg->jump;
-+ x->call = reg->call;
-+ x->unchanging = reg->unchanging;
-+ x->volatil = reg->volatil;
-+ x->in_struct = reg->in_struct;
-+ x->used = reg->used;
-+ x->frame_related = reg->frame_related;
-+ x->return_val = reg->return_val;
-+
-+ x->u.reg.attrs = reg->u.reg.attrs;
-+ return x;
-+}
-+
-+/* Rename the register plus track all locs to undo these changes. */
-+static rtx
-+find_reg_by_no (rtx x, unsigned oldregno)
-+{
-+ if (!x)
-+ return 0;
-+
-+ RTX_CODE code = GET_CODE(x);
-+
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y))
-+ {
-+ if (REGNO(y) == oldregno)
-+ return y;
-+ }
-+ else
-+ {
-+ rtx r = find_reg_by_no (y, oldregno);
-+ if (r)
-+ return r;
-+ }
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ {
-+ rtx z = XVECEXP(x, i, j);
-+ rtx r = find_reg_by_no (z, oldregno);
-+ if (r)
-+ return r;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Collect some data.
-+ */
-+static std::vector<insn_info> infos;
-+typedef std::vector<insn_info>::iterator insn_info_iterator;
-+
-+// insn->u2.insn_uid -> rtx_insn *
-+static std::multimap<int, rtx_insn *> label2jump;
-+typedef std::multimap<int, rtx_insn *>::iterator l2j_iterator;
-+
-+// index -> index
-+static std::multimap<unsigned, unsigned> jump2label;
-+typedef std::multimap<unsigned, unsigned>::iterator j2l_iterator;
-+
-+static std::map<rtx_insn *, insn_info *> insn2info;
-+typedef std::map<rtx_insn *, insn_info *>::iterator i2i_iterator;
-+
-+static std::set<unsigned> scan_starts;
-+typedef std::set<unsigned>::iterator su_iterator;
-+
-+static insn_info * info0;
-+static unsigned usable_regs;
-+
-+static void
-+update_insn2index ()
-+{
-+ infos.reserve (infos.size () * 8 / 7 + 2);
-+ insn2info.clear ();
-+ /* needs a separate pass since the insn_infos require fixed addresses for
->get_index() */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ insn2info.insert (std::make_pair (ii.get_insn (), &ii));
-+ }
-+ info0 = &infos[0];
-+}
-+
-+static void
-+update_label2jump ()
-+{
-+ update_insn2index ();
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.is_label ())
-+ for (l2j_iterator i = label2jump.find (ii.get_insn ()->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
-+ jump2label.insert (std::make_pair (insn2info.find
(i->second)->second->get_index (), index));
-+ }
-+}
-+
-+int
-+insn_info::get_index () const
-+{
-+ insn_info * ii = &infos[0];
-+
-+ if (ii == info0)
-+ {
-+ ptrdiff_t diff = ((char const *) this - (char const *) ii);
-+ unsigned pos = diff / sizeof(insn_info);
-+ if (pos < infos.size ())
-+ return pos;
-+ }
-+
-+// realloc happened...
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ if (infos[i].get_insn () == this->insn)
-+ return i;
-+
-+// whoops!?
-+ return 0;
-+}
-+
-+void
-+insn_info::plus_to_move (rtx_insn * newinsn)
-+{
-+ insn = newinsn;
-+ src_op = (rtx_code) 0;
-+ src_reg = XEXP(PATTERN (newinsn), 1);
-+ insn2info.insert (std::make_pair (insn, this));
-+// usage flags did not change
-+}
-+
-+void
-+insn_info::swap_adds (rtx_insn * newinsn, insn_info & ii)
-+{
-+ insn = newinsn;
-+
-+ std::swap (*this, ii);
-+
-+ insn2info.insert (std::make_pair (insn, this));
-+ insn2info.insert (std::make_pair (ii.insn, &ii));
-+
-+// usage flags did not change
-+}
-+
-+static
-+void
-+replace_reg (rtx x, unsigned regno, rtx newreg, int offset)
-+{
-+ RTX_CODE code = GET_CODE(x);
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ {
-+ rtx y = XEXP(x, i);
-+ if (REG_P(y) && REGNO(y) == regno)
-+ {
-+ XEXP(x, i) = newreg;
-+ if (offset && i + 1 < GET_RTX_LENGTH(code))
-+ {
-+ rtx c = XEXP(x, i + 1);
-+ if (GET_CODE(c) == CONST_INT)
-+ XEXP(x, i + 1) = gen_rtx_CONST_INT (GET_MODE(x), INTVAL(c) + offset);
-+ }
-+ }
-+ else
-+ replace_reg (y, regno, newreg, offset);
-+ }
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ replace_reg (XVECEXP(x, i, j), regno, newreg, offset);
-+ }
-+}
-+
-+void
-+insn_info::a5_to_a7 (rtx a7)
-+{
-+ if (proepi == IN_EPILOGUE && src_mem_reg && get_src_mem_regno () ==
FRAME_POINTER_REGNUM)
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ {
-+ SET_SRC(set) = gen_rtx_MEM (mode, gen_rtx_POST_INC(SImode, a7));
-+ return;
-+ }
-+ }
-+ replace_reg (PATTERN (insn), FRAME_POINTER_REGNUM, a7, -4);
-+}
-+
-+void
-+insn_info::set_insn (rtx_insn * newinsn)
-+{
-+ insn = newinsn;
-+
-+ reset_flags ();
-+
-+ fledder (single_set (insn));
-+}
-+
-+rtx
-+insn_info::make_absolute2base (unsigned regno, unsigned base, rtx with_symbol, bool
apply)
-+{
-+ rtx set = single_set (get_insn ());
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+ rtx reg = gen_raw_REG (SImode, regno);
-+ bool vola = src->volatil;
-+
-+ if (is_dst_mem () && (has_dst_addr () || get_dst_symbol ()) &&
!has_dst_memreg () && get_dst_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_dst_mem_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
-+ {
-+ if (base == addr)
-+ dst = gen_rtx_MEM (mode, reg);
-+ else
-+ dst = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode,
offset)));
-+
-+ if (apply)
-+ {
-+ dst_mem_reg = reg;
-+ dst_mem = true;
-+ dst_mem_addr = offset;
-+ dst_plus = offset != 0;
-+ }
-+ }
-+ }
-+
-+ if (is_src_mem () && (has_src_addr () || get_src_symbol ()) &&
!has_src_memreg () && get_src_symbol () == with_symbol)
-+ {
-+ unsigned addr = get_src_mem_addr ();
-+ unsigned offset = addr - base;
-+ if (offset <= 0x7ffe)
-+ {
-+ if (base == addr)
-+ src = gen_rtx_MEM (mode, reg);
-+ else
-+ src = gen_rtx_MEM (mode, gen_rtx_PLUS(SImode, reg, gen_rtx_CONST_INT (SImode,
offset)));
-+
-+ /* some operation to the same value as dst. eg. eor #5,symbol+8 -> eor #5,8(ax)
*/
-+ if (src_op)
-+ {
-+ if (src_ee)
-+ src = gen_rtx_fmt_ee(src_op, mode, src, gen_rtx_CONST_INT (mode, src_intval));
-+ else
-+ {
-+ if (src_op == SIGN_EXTEND)
-+ {
-+ PUT_MODE_RAW(src, mode == SImode ? HImode : mode == HImode ? QImode : SImode);
-+ src->call = 1;
-+ }
-+ src = gen_rtx_fmt_e(src_op, mode, src);
-+ }
-+ }
-+
-+ if (apply)
-+ {
-+ src_mem_reg = reg;
-+ src_mem = true;
-+ src_mem_addr = offset;
-+ src_plus = offset != 0;
-+ }
-+ }
-+ }
-+
-+ rtx pattern = gen_rtx_SET(dst, src);
-+ src->volatil = vola;
-+
-+ return pattern;
-+}
-+
-+void
-+insn_info::absolute2base (unsigned regno, unsigned base, rtx with_symbol)
-+{
-+ rtx pattern = make_absolute2base (regno, base, with_symbol, true);
-+
-+ SET_INSN_DELETED(insn);
-+ insn = emit_insn_after (pattern, insn);
-+
-+ mark_myuse (regno);
-+
-+ insn2info.insert (std::make_pair (insn, this));
-+}
-+/*
-+ * Reset collected data.
-+ */
-+static void
-+clear (void)
-+{
-+ label2jump.clear ();
-+ jump2label.clear ();
-+ insn2info.clear ();
-+ infos.clear ();
-+ scan_starts.clear ();
-+}
-+
-+/*
-+ * return true if the register is DEAD.
-+ * Do not check at jumps.
-+ */
-+static bool
-+is_reg_dead (unsigned regno, unsigned _pos)
-+{
-+// skip labels.
-+ for (unsigned pos = _pos + 1; pos < infos.size (); ++pos)
-+ {
-+ insn_info & ii = infos[pos];
-+ // skip entries without info
-+ if (ii.is_empty ())
-+ continue;
-+
-+ // not dead if usage is reported in the next statement
-+ return !ii.is_use (regno) && !ii.is_hard (regno);
-+ }
-+ return true;
-+}
-+
-+bool dump_reg_track;
-+void
-+append_reg_cache (FILE * f, rtx_insn * insn)
-+{
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
-+ return;
-+
-+ insn_info & jj = *i->second;
-+ unsigned index = jj.get_index ();
-+ if (index + 1 < infos.size ())
-+ ++index;
-+ insn_info & ii = infos[index];
-+
-+ track_var * track = ii.get_track_var ();
-+ if (track == 0)
-+ return;
-+
-+ fprintf (f, "\n");
-+
-+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
-+ {
-+ rtx v = track->get (regno);
-+ if (v == 0)
-+ continue;
-+
-+// if (GET_CODE(v) == CONST_INT && GET_MODE(v) == VOIDmode)
-+// continue;
-+
-+ fprintf (f, "%s=", reg_names[regno]);
-+
-+ print_inline_rtx (f, v, 12);
-+ fprintf (f, "\n");
-+ }
-+}
-+
-+/* helper stuff to enhance the asm output. */
-+int my_flag_regusage;
-+void
-+append_reg_usage (FILE * f, rtx_insn * insn)
-+{
-+ i2i_iterator i = insn2info.find (insn);
-+ if (i == insn2info.end ())
-+ return;
-+
-+ insn_info & ii = *i->second;
-+
-+ if (f != stderr)
-+ {
-+ if (be_very_verbose > 1)
-+ fprintf (f, "\n\t\t\t\t\t|%d\t", ii.get_index ());
-+ else
-+ fprintf (f, "\n\t\t\t\t\t|\t");
-+ }
-+
-+ fprintf (f, "%c ", ii.in_proepi () == IN_PROLOGUE ? 'p' :
ii.in_proepi () >= IN_EPILOGUE ? 'e' : ' ');
-+
-+ for (int j = 0; j < 8; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse
(j) ? "." : " ");
-+ fprintf (f, "d%d ", j);
-+ }
-+ else
-+ fprintf (f, " ");
-+
-+ for (int j = 8; j < 16; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" : ii.is_myuse
(j) ? "." : " ");
-+ fprintf (f, "a%d ", j - 8);
-+ }
-+ else
-+ fprintf (f, " ");
-+
-+ if (ii.is_use (FIRST_PSEUDO_REGISTER))
-+ fprintf (f, ii.is_def (FIRST_PSEUDO_REGISTER) ? "+cc " : " cc
");
-+ else
-+ fprintf (f, " ");
-+
-+ // append fp usage info if present
-+ if ((ii.get_use () | ii.get_def ()) & ~0xffff)
-+ {
-+ for (int j = 16; j < 24; ++j)
-+ if (ii.is_use (j) || ii.is_def (j))
-+ {
-+ fprintf (f, ii.is_hard (j) ? "!" : " ");
-+ fprintf (f, ii.is_def (j) ? ii.is_use (j) ? "*" : "+" :
ii.is_myuse (j) ? "." : " ");
-+ fprintf (f, "f%d ", j - 16);
-+ }
-+ else
-+ fprintf (f, " ");
-+ }
-+
-+ if (f == stderr)
-+ fprintf (f, "\n");
-+
-+}
-+
-+/*
-+ * Helper function to dump the code.
-+ * Sometimes used during debugging.
-+ */
-+static void
-+dump_insns (char const * name, bool all)
-+{
-+ fprintf (stderr, "====================================: %s\n", name);
-+ if (all)
-+ {
-+ for (rtx_insn * insn = get_insns (); insn && insn != infos[0].get_insn ();
insn = NEXT_INSN (insn))
-+ debug_rtx (insn);
-+ }
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ fprintf (stderr, "%d: ", i);
-+
-+ rtx_insn * insn = infos[i].get_insn ();
-+ if (i < infos.size ())
-+ append_reg_usage (stderr, insn);
-+
-+ fprintf (stderr, "\t");
-+ debug_rtx (insn);
-+
-+ if (all)
-+ {
-+ rtx_insn * p = i + 1 < infos.size () ? infos[i + 1].get_insn () : 0;
-+ for (rtx_insn * q = NEXT_INSN (insn); q && q != p; q = NEXT_INSN (q))
-+ debug_rtx (q);
-+ }
-+ }
-+}
-+
-+/* This is the important function to track register usage plus hard/live state.
-+ *
-+ * Start at bottom and work upwards. On all labels trigger all jumps referring to this
label.
-+ * A set destination into a register is a def. All other register references are an
use.
-+ * Hard registers cann't be renamed and are mandatory for regparms and
asm_operands.
-+ */
-+static void
-+update_insn_infos (void)
-+{
-+ /* add all return (jump outs) and start analysis there. */
-+ std::set<unsigned> & todo = scan_starts;
-+
-+ if (todo.begin () == todo.end ())
-+ todo.insert (infos.size () - 1);
-+
-+ bool locka4 = flag_pic >= 3;
-+
-+ while (!todo.empty ())
-+ {
-+ int start = *todo.begin ();
-+ todo.erase (todo.begin ());
-+ insn_info ii = infos[start];
-+
-+ enum proepis proepi = ii.in_proepi ();
-+
-+ // mark sp reg as used.
-+ if (proepi >= IN_EPILOGUE)
-+ ii.mark_use (STACK_POINTER_REGNUM), infos[start].mark_use (STACK_POINTER_REGNUM);
-+
-+ for (int pos = start; pos >= 0; --pos)
-+ {
-+ insn_info & pp = infos[pos];
-+ rtx_insn * insn = pp.get_insn ();
-+
-+ // do not run into previous epilogue
-+ if (pp.in_proepi () >= IN_EPILOGUE && !proepi)
-+ break;
-+
-+ proepi = pp.in_proepi ();
-+
-+ /* no new information -> break. */
-+ if (pos != start && pp.is_visited () && !JUMP_P(insn) &&
pp.contains (ii))
-+ break;
-+
-+ ii.clear_hard_def ();
-+ ii.merge (pp);
-+
-+ if (LABEL_P(insn))
-+ {
-+ /* work on all jumps referring to that label. */
-+ l2j_iterator i = label2jump.find (insn->u2.insn_uid);
-+
-+ /* no jump to here -> mark all registers as hard regs.
-+ * This label is maybe used in an exception handler.
-+ * Marking as hard also avoids stack frame removal.
-+ */
-+ if (i == label2jump.end ())
-+ infos[pos + 1].make_hard ();
-+ else
-+ for (l2j_iterator k = i; i != label2jump.end () && i->first == k->first;
++i)
-+ {
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j != insn2info.end ())
-+ {
-+ unsigned index = j->second->get_index ();
-+ insn_info & jj = infos[index];
-+ if (!jj.is_visited () || !jj.contains (ii))
-+ {
-+ jj.updateWith (ii);
-+ todo.insert (index);
-+ }
-+ }
-+ }
-+
-+ if (pos == start)
-+ pp.mark_visited ();
-+
-+ /* check previous insn for jump */
-+ if (pos > 0 && infos[pos - 1].is_jump ())
-+ {
-+ rtx_insn * prev = infos[pos - 1].get_insn ();
-+ rtx set = single_set (prev);
-+ /* unconditional? -> break! */
-+ if (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE)
-+ break;
-+ }
-+
-+ continue;
-+ }
-+
-+ pp.mark_visited ();
-+
-+ rtx pattern = PATTERN (insn);
-+ insn_info use (insn);
-+ use.scan ();
-+ if (locka4 && (use.get_myuse () & (1 << PIC_REG)))
-+ use.mark_hard (PIC_REG);
-+
-+ /* do not mark a node as visited, if it's in epilogue and not yet visited. */
-+ if (CALL_P(insn) || JUMP_P(insn))
-+ {
-+ if (pos != start && ii.in_proepi ())
-+ {
-+ su_iterator k = scan_starts.find (pos);
-+ if (k != scan_starts.end ())
-+ {
-+ pp.clear_visited ();
-+ break;
-+ }
-+ }
-+ }
-+ else if (GET_CODE (pattern) == USE || GET_CODE (pattern) == CLOBBER)
-+ {
-+ use.make_clobber ();
-+ }
-+ else if (single_set (insn) == 0)
-+ use.make_hard ();
-+ else
-+ /* if not cc0 defined check for mod. */
-+ if (!use.is_def (FIRST_PSEUDO_REGISTER))
-+ {
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn), insn);
-+ if (cc_status.value1 || cc_status.value2)
-+ use.mark_def (FIRST_PSEUDO_REGISTER);
-+ }
-+
-+ // TODO: use 2 bits for data regs, to indicate mode size
-+// // also check mode size if < 4, it's also a use for data registers.
-+// if (pp.get_dst_reg () && pp.get_dst_regno () < 8 &&
GET_MODE_SIZE(pp.get_mode()) < 4)
-+// use.mark_use (pp.get_dst_regno ());
-+
-+ /* mark not renameable in prologue/epilogue. */
-+ if (pp.in_proepi () != IN_CODE)
-+ use.make_hard ();
-+
-+ ii.merge (use);
-+ pp.update (ii);
-+ ii.updateWith (use);
-+ }
-+ }
-+
-+ /* fill the mask of general used regs. */
-+ insn_info zz;
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (ii.in_proepi () != IN_PROLOGUE)
-+ break;
-+
-+ zz.or_use (ii);
-+ }
-+
-+ /* always allow a0/a1, d0/d1. */
-+ usable_regs = zz.get_use () | 0x303;
-+ if (flag_pic)
-+ usable_regs &= ~(1 << PIC_REG);
-+
-+ if (infos.size () && infos[0].is_use (FRAME_POINTER_REGNUM))
-+ usable_regs &= ~(1 << FRAME_POINTER_REGNUM);
-+
-+ usable_regs &= ~(1 << STACK_POINTER_REGNUM);
-+}
-+
-+enum AbortCodes
-+{
-+ E_OK, E_NO_JUMP_LABEL, E_JUMP_TABLE_MISMATCH, E_JUMP_GOTO_LABEL, E_SP_MISMATCH
-+};
-+
-+/*
-+ * Create a filtered view of insns - keep only those to work with.
-+ */
-+static unsigned
-+update_insns ()
-+{
-+ rtx_insn *insn, *next;
-+ unsigned result = 0;
-+ rtx jump_table = 0;
-+
-+ clear ();
-+
-+ enum proepis inproepilogue = IN_PROLOGUE;
-+ /* create a vector with relevant insn. */
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P (insn) || LABEL_P(insn) || JUMP_P(insn) || CALL_P(insn))
-+ {
-+
-+ infos.push_back (insn_info (insn, inproepilogue));
-+ insn_info & ii = infos[infos.size () - 1];
-+
-+ if (JUMP_P(insn))
-+ {
-+ if (inproepilogue || ANY_RETURN_P(PATTERN (insn)))
-+ {
-+ if (ANY_RETURN_P(PATTERN (insn)))
-+ ii.set_proepi (IN_EPILOGUE);
-+
-+ scan_starts.insert (infos.size () - 1);
-+ inproepilogue = IN_CODE;
-+ rtx set = single_set (insn);
-+ if (ANY_RETURN_P(PATTERN (insn))
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE))
-+ continue;
-+ }
-+
-+ ii.mark_jump ();
-+ if (jump_table)
-+ {
-+ if (XEXP(jump_table, 0) != insn)
-+ {
-+ if (be_very_verbose)
-+ {
-+ debug_rtx (insn);
-+ debug_rtx (jump_table);
-+ }
-+ result = E_JUMP_TABLE_MISMATCH;
-+ jump_table = 0;
-+ continue;
-+ }
-+
-+ // -> jump_table_data
-+ rtx table = PATTERN (XEXP(jump_table, 1));
-+ if (GET_CODE(table) == ADDR_DIFF_VEC || GET_CODE(table) == ADDR_VEC)
-+ {
-+ int k = GET_CODE(table) == ADDR_DIFF_VEC;
-+ for (int j = 0; j < XVECLEN(table, k); ++j)
-+ {
-+ rtx ref = XVECEXP(table, k, j);
-+ if (!LABEL_REF_NONLOCAL_P(ref))
-+ {
-+ rtx label = XEXP(ref, 0);
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ ii.set_proepi (IN_EPILOGUE);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ if (be_very_verbose)
-+ {
-+ debug_rtx (insn);
-+ debug_rtx (jump_table);
-+ }
-+ result = E_JUMP_GOTO_LABEL;
-+ jump_table = 0;
-+ continue;
-+ }
-+ jump_table = 0;
-+ }
-+ else
-+ {
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (!label)
-+ {
-+ if (be_very_verbose)
-+ debug_rtx (insn);
-+ result = E_NO_JUMP_LABEL;
-+ continue;
-+ }
-+ label2jump.insert (std::make_pair (label->u2.insn_uid, insn));
-+ }
-+ }
-+ else if (LABEL_P(insn))
-+ {
-+ ii.mark_label ();
-+ jump_table = 0;
-+ ii.set_proepi (inproepilogue = IN_CODE);
-+ if (infos.size () > 1)
-+ scan_starts.insert (infos.size () - 1);
-+ }
-+ else if (CALL_P(insn))
-+ {
-+ if (insn->jump)
-+ {
-+ ii.set_proepi (IN_EPILOGUE);
-+ ii.mark_jump ();
-+ scan_starts.insert (infos.size () - 1);
-+ }
-+ ii.mark_call ();
-+ if (inproepilogue)
-+ {
-+ scan_starts.insert (infos.size () - 1);
-+ inproepilogue = IN_CODE;
-+ }
-+ }
-+ else
-+ {
-+ rtx set = single_set (insn);
-+ if (set)
-+ ii.fledder (set);
-+
-+ for (rtx next, note = REG_NOTES(insn); note; note = next)
-+ {
-+ next = XEXP(note, 1);
-+ if (REG_NOTE_KIND (note) == REG_LABEL_OPERAND)
-+ {
-+ jump_table = XEXP(note, 0);
-+ }
-+ }
-+
-+ }
-+ }
-+ else if (NOTE_P(insn))
-+ {
-+ if (NOTE_KIND(insn) == NOTE_INSN_PROLOGUE_END)
-+ inproepilogue = IN_CODE;
-+ else if (NOTE_KIND(insn) == NOTE_INSN_EPILOGUE_BEG)
-+ inproepilogue = IN_EPILOGUE;
-+ }
-+ }
-+ scan_starts.insert (infos.size () - 1);
-+ update_insn2index ();
-+ update_insn_infos ();
-+
-+ return result;
-+}
-+
-+/* convert the lowest set bit into a register number. */
-+static int
-+bit2regno (unsigned bit)
-+{
-+ if (!bit)
-+ return -1;
-+
-+ unsigned regno = 0;
-+ while (!(bit & 1))
-+ {
-+ ++regno;
-+ bit >>= 1;
-+ }
-+ return regno;
-+}
-+
-+/* check if that register is touched between from and to, excluding from and to .*/
-+static bool
-+is_reg_touched_between (unsigned regno, int from, int to)
-+{
-+ for (int index = from + 1; index < to; ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.is_myuse (regno) || ii.is_def (regno))
-+ return true;
-+ }
-+ return false;
-+}
-+
-+/*
-+ * search backward and find the initial assignment for that regno.
-+ */
-+static unsigned
-+find_start (unsigned start, unsigned rename_regno)
-+{
-+ /* search the start. */
-+ while (start > 0)
-+ {
-+ unsigned startm1 = start - 1;
-+
-+ /* do not run over RETURNS */
-+ insn_info & jj = infos[start];
-+
-+ /* stop at labels. If a label is a start pos, a search is maybe started again. */
-+ if (jj.is_label ())
-+ break;
-+
-+ insn_info & bb = infos[startm1];
-+ if (jj.in_proepi () == IN_CODE && bb.in_proepi () >= IN_EPILOGUE)
-+ break;
-+
-+ /* found the definition without use. */
-+ if (jj.is_def (rename_regno) && !jj.is_use (rename_regno))
-+ break;
-+
-+ start = startm1;
-+ }
-+ return start;
-+}
-+
-+/*
-+ * Always prefer lower register numbers within the class.
-+ */
-+static unsigned
-+opt_reg_rename (void)
-+{
-+ update_label2jump ();
-+// dump_insns ("rename", 1);
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ /* do not rename if register is hard or used in same statement. */
-+ const unsigned rename_regbit = ii.get_regbit ();
-+ if (!rename_regbit)
-+ continue;
-+
-+ const unsigned rename_regno = bit2regno (rename_regbit);
-+
-+ /* get the mask for free registers. */
-+ unsigned mask = ii.get_free_mask ();
-+
-+ /* the mask contains the current src register. Add this register to the mask if
it's dead here. */
-+ if (ii.get_src_reg () && is_reg_dead (ii.get_src_regno (), index))
-+ mask |= ii.get_use ();
-+
-+ /* do not use a4 if compiling baserel */
-+ if (flag_pic >= 3)
-+ mask &= ~(1 << PIC_REG);
-+
-+ if (!mask)
-+ continue;
-+
-+ /* first = pos to start, second indicates to treat def as use. */
-+ std::set<unsigned> todo;
-+ std::set<unsigned> found;
-+ if (index + 1 < infos.size ())
-+ todo.insert (index + 1);
-+
-+ found.insert (index);
-+ /* a register was defined, follow all branches. */
-+ while (mask && todo.begin () != todo.end ())
-+ {
-+ unsigned runpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-+
-+// printf ("runpos %d \n", runpos); fflush (stdout);
-+ for (unsigned pos = runpos; mask && pos < infos.size (); ++pos)
-+ {
-+ /* already searched. */
-+ if (found.find (pos) != found.end ())
-+ break;
-+
-+ rtx_insn * insn = infos[pos].get_insn ();
-+ if (LABEL_P(insn))
-+ {
-+ found.insert (pos);
-+
-+ /* for each jump to this label:
-+ * check if the reg was used at that jump.
-+ * if used, find def
-+ */
-+ for (l2j_iterator i = label2jump.find (insn->u2.insn_uid), k = i;
-+ i != label2jump.end () && i->first == k->first; ++i)
-+ {
-+ i2i_iterator j = insn2info.find (i->second);
-+ if (j == insn2info.end ())
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ unsigned startat = j->second->get_index ();
-+ if (found.find (startat) != found.end () || !infos[startat].is_use
(rename_regno))
-+ continue;
-+
-+ unsigned start = find_start (startat, rename_regno);
-+// printf ("label %d <- jump %d : start %d\n", pos, startat, start);
fflush (stdout);
-+ todo.insert (start);
-+ }
-+
-+ /* if this label is at a start, check if it is reachable from the previous insn,
-+ * and if, check for use then search start. */
-+ if (pos > 0)
-+ {
-+ insn_info & bb = infos[pos - 1];
-+ rtx set = single_set (bb.get_insn ());
-+ if (ANY_RETURN_P(bb.get_insn ())
-+ || (set && SET_DEST(set) == pc_rtx && GET_CODE(SET_SRC(set)) !=
IF_THEN_ELSE))
-+ continue;
-+
-+// printf ("label start check %d use %d\n", pos, bb.is_use
(rename_regno) || bb.is_def(rename_regno)); fflush (stdout);
-+
-+ if (bb.is_use (rename_regno) || bb.is_def (rename_regno))
-+ {
-+ unsigned start = find_start (pos - 1, rename_regno);
-+ todo.insert (start);
-+// printf ("label %d : start %d \n", pos, start); fflush (stdout);
-+ }
-+ }
-+
-+ continue;
-+ }
-+
-+ insn_info & jj = infos[pos];
-+
-+ /* marked as hard reg -> invalid rename */
-+ if (jj.get_use () & jj.get_hard () & rename_regbit)
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ /* not used. and not a def */
-+ if (pos == runpos && (jj.get_def () & rename_regbit))
-+ {
-+ /* continue since this pos was added by start search. */
-+ }
-+ else if (!(jj.get_use () & rename_regbit))
-+ break;
-+
-+ /* abort if some insn using this reg uses more than 1 reg. */
-+ if ((jj.get_myuse () & rename_regbit) && GET_MODE_SIZE(jj.get_mode())
> 4)
-+ {
-+ mask = 0;
-+ break;
-+ }
-+
-+ /* update free regs. */
-+ mask &= ~jj.get_use ();
-+ mask &= ~jj.get_def ();
-+ if (!mask)
-+ break;
-+
-+ found.insert (pos);
-+
-+ /* follow jump and/or next insn. */
-+ if (JUMP_P(insn))
-+ {
-+ for (j2l_iterator i = jump2label.find (pos), k = i; i != jump2label.end ()
&& i->first == k->first;
-+ ++i)
-+ {
-+ unsigned label_index = i->second;
-+
-+ /* add the label to the search list. */
-+ insn_info & bb = infos[label_index + 1];
-+ if (found.find (label_index) == found.end () && bb.is_use
(rename_regno))
-+ {
-+// printf ("jump %d -> label %d \n", pos, label_index); fflush
(stdout);
-+ todo.insert (label_index);
-+ }
-+ }
-+ rtx set = single_set (insn);
-+ if (!set)
-+ {
-+ // it's a parallel pattern - search the set pc = ...
-+ rtx pat = PATTERN (insn);
-+ for (int j = XVECLEN (pat, 0) - 1; j >= 0; j--)
-+ {
-+ rtx x = XVECEXP(pat, 0, j);
-+ if (XEXP(x, 0) == pc_rtx)
-+ {
-+ set = x;
-+ break;
-+ }
-+ }
-+ }
-+ rtx jmpsrc = set ? SET_SRC(set) : 0;
-+ if (!jmpsrc || GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ break;
-+ }
-+ }
-+ }
-+
-+ if (mask)
-+ {
-+ int oldregno = bit2regno (rename_regbit);
-+ int newregno = bit2regno (mask);
-+
-+ /* check the renamed insns. */
-+ std::vector<unsigned> positions;
-+ for (std::set<unsigned>::iterator i = found.begin (); i != found.end (); ++i)
-+ {
-+ insn_info & rr = infos[*i];
-+ rtx_insn * insn = rr.get_insn ();
-+
-+ /* get rename locations. */
-+ rtx from = find_reg_by_no (PATTERN (insn), oldregno);
-+ if (from)
-+ {
-+ rtx to = gen_raw_REG (GET_MODE(from), newregno);
-+ validate_replace_rtx_group (from, to, insn);
-+
-+ positions.push_back (*i);
-+ }
-+ }
-+
-+ if (!apply_change_group ())
-+ continue;
-+
-+ log ("(r) opt_reg_rename %s -> %s (%d locs, start at %d)\n",
reg_names[oldregno], reg_names[newregno],
-+ positions.size (), index);
-+
-+ if (be_verbose)
-+ {
-+ for (std::vector<unsigned>::iterator i = positions.begin (); i !=
positions.end (); ++i)
-+ printf ("%d ", *i);
-+ printf ("\n");
-+ fflush (stdout);
-+ }
-+
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * #1 propagate a->b->a moves out of a loop.
-+ *
-+ * consider a loop:
-+ *
-+ * .L1
-+ * ...
-+ * move d0, a0 ; (1)
-+ * ...
-+ * move xy, (a0)+
-+ * ...
-+ * move a0, d0 ; (2)
-+ * ...
-+ * jxx .L1
-+ *
-+ * Then the statements (1) and (2) can be moved out of the loop:
-+ *
-+ * move d0, a0 ; (3)
-+ * .L1
-+ * ...
-+ * move *, (a0)+ ; a0 is modified somehow
-+ * ...
-+ * jxx .L1
-+ * move a0, d0 ; (4)
-+ *
-+ * if all criteria are met:
-+ *
-+ * a) no other jump to .L1 -> (LABEL_NUSES(insn) == 1)
-+ * b) no other use of d0 inside the loop
-+ * c) no other use of a0 before (1)
-+ * d) no other use of a1 after (2)
-+ *
-+ * Optional:
-+ * - omit (4) if d0 is dead
-+ *
-+ * this will e.g. convert
-+ .L6:
-+ move.l d0,a1
-+ move.b (a1)+,d1
-+ move.l a1,d0
-+ move.b d1,(a0)+
-+ cmp.b #0, d1
-+ jne .L6
-+ * to
-+ move.l d0,a1
-+ .L6:
-+ move.b (a1)+,d1
-+ move.b d1,(a0)+
-+ cmp.b #0, d1
-+ jne .L6
-+
-+ *
-+ * Also allow exit jumps, if the modification of the reg is const
-+ * and insert a correction after the exit label.
-+ * The label must only be reachable by the exit jump.
-+ */
-+static unsigned
-+opt_propagate_moves ()
-+{
-+ unsigned change_count = 0;
-+ rtx_insn * current_label = 0;
-+ unsigned current_label_index;
-+ std::vector<unsigned> reg_reg;
-+ std::vector<rtx_insn *> jump_out;
-+
-+ /* start at 1 since there must be an insn before the label. */
-+ for (unsigned index = 1; index < infos.size (); ++index)
-+ {
-+ rtx_insn * insn = infos[index].get_insn ();
-+
-+ if (LABEL_P(insn))
-+ {
-+ if (LABEL_NUSES(insn) == 1)
-+ {
-+ current_label = insn;
-+ current_label_index = index;
-+ reg_reg.clear ();
-+ jump_out.clear ();
-+ }
-+ else
-+ current_label = 0;
-+ }
-+
-+ if (current_label == 0)
-+ continue;
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ // check for set reg, reg
-+ rtx set = single_set (insn);
-+ if (set)
-+ {
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+ if (REG_P(src) && REG_P(dst))
-+ reg_reg.push_back (index);
-+ }
-+ else
-+ current_label = 0;
-+
-+ continue;
-+ }
-+
-+ if (JUMP_P(insn))
-+ {
-+ rtx_insn * label = (rtx_insn *) JUMP_LABEL(insn);
-+ if (label != current_label)
-+ {
-+ /* collect the labels for a later check if a fixup is possible. */
-+ if (LABEL_NUSES(label) == 1 && BARRIER_P(PREV_INSN (label)))
-+ jump_out.push_back (label);
-+ else
-+ current_label = 0;
-+ continue;
-+ }
-+
-+ if (reg_reg.size () > 1)
-+ {
-+ /* Search for reg/reg pairs. */
-+ for (std::vector<unsigned>::iterator i = reg_reg.begin (); i != reg_reg.end
() && i + 1 != reg_reg.end ();
-+ )
-+ {
-+ bool inc = true;
-+ for (std::vector<unsigned>::iterator j = i + 1; j != reg_reg.end ();)
-+ {
-+ rtx_insn * ii = infos[*i].get_insn ();
-+ rtx seti = single_set (ii);
-+ rtx srci = SET_SRC(seti);
-+ rtx dsti = SET_DEST(seti);
-+ rtx_insn * jj = infos[*j].get_insn ();
-+ rtx setj = single_set (jj);
-+ rtx srcj = SET_SRC(setj);
-+ rtx dstj = SET_DEST(setj);
-+
-+ if (rtx_equal_p (srci, dstj) && rtx_equal_p (srcj, dsti))
-+ {
-+ /* Ensure correct usage. */
-+ if (is_reg_touched_between (REGNO(srci), current_label_index, *i) // label ... move
src,x
-+ || is_reg_touched_between (REGNO(srci), *i, *j) // move src,x ... move x,src
-+ || is_reg_touched_between (REGNO(srci), *j, index) // move x,src ... jcc
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // label ... move src,x
-+ || is_reg_touched_between (REGNO(dsti), *j, index) // move x,src ... jcc
-+ )
-+ {
-+ ++j;
-+ continue;
-+ }
-+
-+ std::vector<int> fixups;
-+
-+ /* if there are jumps out of the loop,
-+ * check if the modification occurs before the jump,
-+ * and if, that it's a plus const.
-+ */
-+ if (jump_out.size ())
-+ {
-+ std::vector<rtx_insn *>::iterator label_iter = jump_out.begin ();
-+ int fixup = 0;
-+
-+ for (unsigned k = *i + 1; k != *j; ++k)
-+ {
-+ rtx_insn * check = infos[k].get_insn ();
-+ if (JUMP_P(check))
-+ {
-+ fixups.push_back (fixup);
-+ if (++label_iter == jump_out.end ())
-+ break;
-+ continue;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, PATTERN (check)))
-+ {
-+ /* right now only support auto_incs. */
-+ rtx set = single_set (check);
-+ rtx src = SET_SRC(set);
-+ rtx dst = SET_DEST(set);
-+
-+ if (reg_overlap_mentioned_p (dsti, dst))
-+ {
-+ if (REG_P(dst))
-+ break;
-+ if (!MEM_P(dst))
-+ break;
-+
-+ rtx x = XEXP(dst, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+
-+ if (reg_overlap_mentioned_p (dsti, src))
-+ {
-+ if (REG_P(src))
-+ fixup += 0;
-+ else
-+ {
-+ if (!MEM_P(src))
-+ break;
-+
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == REG)
-+ fixup += 0; // direct use
-+ else if (GET_CODE(x) == PRE_INC ||
-+ GET_CODE(x) == POST_INC)
-+ fixup -= GET_MODE_SIZE(GET_MODE(dst));
-+ else if (GET_CODE(dst) == PRE_DEC ||
-+ GET_CODE(dst) == POST_DEC)
-+ fixup += GET_MODE_SIZE(GET_MODE(dst));
-+ else
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /* got a fixup for all jump_outs? */
-+ if (fixups.size () == jump_out.size ())
-+ {
-+ rtx_insn * before = infos[current_label_index - 1].get_insn ();
-+ rtx_insn * after = infos[index + 1].get_insn ();
-+ rtx bset = single_set (before);
-+
-+ log ("(p) propagate_moves condition met, moving regs %s, %s\n",
-+ reg_names[REGNO(srci)],
-+ reg_names[REGNO(dsti)]);
-+
-+ /* Move in front of loop and mark as dead. */
-+ rtx_insn * newii = make_insn_raw (PATTERN (ii));
-+ SET_INSN_DELETED(ii);
-+
-+ /* Plus check if the reg was just loaded. */
-+ if (bset)
-+ {
-+ rtx bdst = SET_DEST(bset);
-+ if (REG_P(bdst) && REGNO(bdst) == REGNO(srci))
-+ {
-+ SET_SRC(PATTERN(newii)) = SET_SRC(bset);
-+// SET_INSN_DELETED(ii);
-+ }
-+ }
-+ else
-+ add_reg_note (newii, REG_DEAD, srci);
-+
-+ add_insn_after (newii, before, 0);
-+
-+ /* Move behind loop - into next BB. */
-+ rtx_insn * newjj = make_insn_raw (PATTERN (jj));
-+ add_insn_before (newjj, after, 0);
-+ SET_INSN_DELETED(jj);
-+
-+ reg_reg.erase (j);
-+ reg_reg.erase (i);
-+ j = reg_reg.end ();
-+ inc = false;
-+
-+ /* add fixes if there were jumps out of the loop. */
-+ if (jump_out.size ())
-+ {
-+ log ("(p) propagate_moves fixing %d jump outs\n", jump_out.size ());
-+
-+ for (unsigned k = 0; k < jump_out.size (); ++k)
-+ {
-+ rtx neu = gen_rtx_SET(
-+ dstj, gen_rtx_PLUS (Pmode, dsti, gen_rtx_CONST_INT (Pmode, fixups[k])));
-+ emit_insn_after (neu, jump_out[k]);
-+ }
-+ }
-+ ++change_count;
-+ }
-+ }
-+ if (inc)
-+ ++j;
-+ }
-+ if (inc)
-+ ++i;
-+ }
-+ }
-+ current_label = 0;
-+ }
-+ }
-+ return change_count;
-+}
-+
-+/**
-+ * Search for
-+ *
-+ * mov x,reg
-+ * mov reg,x
-+ * cmp #0, reg
-+ * jxx
-+ *
-+ * patterns.
-+ *
-+ * Use a simple state machine to find the patterns.
-+ */
-+static unsigned
-+opt_strcpy ()
-+{
-+ unsigned change_count = 0;
-+#if HAVE_cc0
-+ rtx_insn * x2reg = 0;
-+ rtx_insn * reg2x;
-+ unsigned int regno;
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ rtx_insn * insn = infos[index].get_insn ();
-+
-+ if (!NONJUMP_INSN_P(insn))
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-+
-+ rtx set = single_set (insn);
-+ if (!set)
-+ {
-+ x2reg = 0;
-+ continue;
-+ }
-+
-+ if (x2reg && reg2x)
-+ {
-+ rtx src = SET_SRC(set);
-+ if (GET_CODE(src) == COMPARE)
-+ {
-+ rtx dst = XEXP(src, 0);
-+ src = XEXP(src, 1);
-+
-+// if (CONST_INT_P(src) && INTVAL(src) == 0 && find_reg_note
(insn, REG_DEAD, dst))
-+ if (REG_P(dst) && CONST_INT_P(src) && INTVAL(src) == 0 &&
is_reg_dead (REGNO(dst), index))
-+ {
-+ /* now check via NOTICE_UPDATE_CC*/
-+ NOTICE_UPDATE_CC(PATTERN (reg2x), reg2x);
-+ if (cc_status.flags == 0 && rtx_equal_p (dst, cc_status.value2))
-+ {
-+ rtx pattern = gen_rtx_SET(SET_DEST(single_set (reg2x)), SET_SRC(single_set
(x2reg)));
-+ rtx_insn * newinsn = make_insn_raw (pattern);
-+
-+ if (!insn_invalid_p (newinsn, 0))
-+ {
-+ log ("(s) opt_strcpy condition met, removing compare and joining insns - omit
reg %s\n",
-+ reg_names[REGNO(dst)]);
-+
-+ SET_INSN_DELETED(x2reg);
-+ SET_INSN_DELETED(reg2x);
-+ SET_INSN_DELETED(insn);
-+
-+ insn = emit_insn_after (pattern, reg2x);
-+ insn_invalid_p (insn, 0);
-+
-+ ++change_count;
-+ }
-+ }
-+ }
-+ x2reg = 0;
-+ continue;
-+ }
-+ reg2x = 0;
-+ }
-+
-+ /* check for reg2x first, maybe fallback to x2reg. */
-+ if (x2reg && reg2x == 0)
-+ {
-+ if (REG_P(SET_SRC(set)) && REGNO(SET_SRC(set)) == regno)
-+ {
-+ reg2x = insn;
-+ continue;
-+ }
-+ x2reg = 0;
-+ }
-+
-+ /* check for a match for x2reg. */
-+ if (x2reg == 0)
-+ {
-+ if (REG_P(SET_DEST(set)))
-+ {
-+ x2reg = insn;
-+ reg2x = 0;
-+ regno = REGNO(SET_DEST(set));
-+ }
-+ }
-+ }
-+#endif
-+ return change_count;
-+}
-+
-+/*
-+ * convert
-+ *
-+ * set reg1, plus (reg2, const)
-+ * set mem(reg2), y
-+ *
-+ * ->
-+ * set reg1, reg2
-+ * set mem(reg1+), y
-+ *
-+ * if size of postinc == const
-+ *
-+ (insn 33 32 35 4 (set (reg/v/f:SI 8 a0 [orig:47 s ] [47])
-+ (plus:SI (reg/v/f:SI 9 a1 [orig:46 s ] [46])
-+ (const_int 1 [0x1]))) sn.c:5 141 {*addsi3_internal}
-+ (nil))
-+ (insn 36 35 37 4 (set (mem:QI (reg/v/f:SI 9 a1 [orig:46 s ] [46]) [0 MEM[base: s_17,
offset: 4294967295B]+0 S1 A8])
-+ (mem:QI (post_inc:SI (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])) [0 MEM[base: s2_19, offset:
4294967295B]+0 S1 A8])) sn.c:5 46 {*m68k.md:1083}
-+ (expr_list:REG_INC (reg/v/f:SI 10 a2 [orig:53 s2 ] [53])
-+ (nil)))
-+ */
-+static unsigned
-+opt_commute_add_move (void)
-+{
-+ unsigned change_count = 0;
-+
-+ for (unsigned index = 0; index + 1 < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.get_dst_regno () < 8 || ii.get_dst_regno () > 15 || ii.get_src_op ()
!= PLUS
-+ || ii.get_src_regno () == ii.get_dst_regno () || !ii.get_src_intval ())
-+ continue;
-+
-+ insn_info & jj = infos[index + 1];
-+
-+ if (!jj.get_dst_mem_reg () || jj.get_dst_mem_regno () != ii.get_src_regno ()
-+ || jj.get_src_regno () == ii.get_dst_regno () || GET_MODE_SIZE(jj.get_mode()) !=
ii.get_src_intval ())
-+ continue;
-+
-+ rtx_insn * insn = ii.get_insn ();
-+
-+ rtx_insn * next = jj.get_insn ();
-+ rtx set2 = single_set (next);
-+ rtx dst = SET_DEST(set2);
-+ if (!MEM_P(dst))
-+ continue;
-+
-+ rtx pinc = gen_rtx_POST_INC(GET_MODE(dst), ii.get_dst_reg ());
-+ rtx newmem = replace_equiv_address_nv (dst, pinc);
-+
-+ rtx_insn * newinsn = make_insn_raw (gen_rtx_SET(ii.get_dst_reg (), ii.get_src_reg
()));
-+
-+ if (!insn_invalid_p (newinsn, 1) && validate_change (next,
&SET_DEST(set2), newmem, 1) && apply_change_group ())
-+ {
-+ log ("(a) commute_add_move found\n");
-+
-+ SET_INSN_DELETED(insn);
-+
-+ insn = emit_insn_before (newinsn, next);
-+
-+ add_reg_note (next, REG_INC, ii.get_dst_reg ());
-+
-+ ++change_count;
-+ }
-+ else
-+ cancel_changes (0);
-+ }
-+ return change_count;
-+}
-+
-+/*
-+ * Replace
-+ *
-+ * move x,dx
-+ * cmp dx,dy
-+ *
-+ * if dx and dy are both dead after compare.
-+ *
-+ * with
-+ *
-+ * sub #n,dx
-+ *
-+ d0 d1 d2 a0 a1 a7 (insn 99 59 41 7 (set (reg:SI 2 d2)
-+ (const_int 1 [0x1])) sn.c:8 38 {*movsi_m68k}
-+ (nil))
-+ d0 d1 d2 a0 a1 a7 (insn 41 99 42 7 (set (cc0)
-+ (compare (reg/v:SI 1 d1 [orig:54 n ] [54])
-+ (reg:SI 2 d2))) sn.c:8 16 {*m68k.md:499}
-+ (expr_list:REG_DEAD (reg:SI 2 d2)
-+ (expr_list:REG_DEAD (reg/v:SI 1 d1 [orig:54 n ] [54])
-+ (nil))))
-+ *
-+ */
-+static unsigned
-+opt_const_cmp_to_sub (void)
-+{
-+ unsigned change_count = 0;
-+#if HAVE_cc0
-+ if (infos.size () < 2)
-+ return change_count;
-+
-+ unsigned lastsub = 0;
-+ for (unsigned index = infos.size () - 2; index > 0; --index)
-+ {
-+ insn_info & i1 = infos[index];
-+
-+ /* we wan't a compare or tst insn, */
-+ if (!i1.is_compare ())
-+ continue;
-+
-+ if (GET_MODE_SIZE(i1.get_mode()) > 4 || !i1.is_dst_reg () ||
REGNO(i1.get_dst_reg()) > 7)
-+ continue;
-+
-+ /* src must be a reg dead register with a constant - or a #0 */
-+ if (!i1.get_src_reg () && (!i1.is_src_const () || i1.get_src_op () ==
PLUS))
-+ continue;
-+
-+ /* allow an alive reg, if life ends at previous handled sub. */
-+ int lastsubval = 0;
-+ if (lastsub == index + 3)
-+ {
-+ insn_info & pp = infos[lastsub];
-+ if (pp.get_dst_regno () != i1.get_dst_regno ())
-+ continue;
-+ lastsubval = pp.get_src_intval ();
-+
-+ // but still check for usage after this jump
-+ j2l_iterator l = jump2label.find (index + 2);
-+ if (l == jump2label.end ())
-+ continue;
-+
-+ insn_info & label = infos[l->second + 1];
-+ if (label.is_use (i1.get_dst_regno ()))
-+ continue;
-+ }
-+ else if (!is_reg_dead (i1.get_dst_regno (), index))
-+ continue;
-+
-+ insn_info & i0 = infos[index - 1];
-+ int intval = 0;
-+ /* compare with register - check previous insn for load with constant. */
-+ if (i1.is_src_reg ())
-+ {
-+ if (!is_reg_dead (i1.get_src_regno (), index))
-+ continue;
-+
-+ if (GET_MODE_SIZE(i0.get_mode()) > 4)
-+ continue;
-+
-+ if (!i0.is_dst_reg () || !i0.is_src_const () || i0.get_src_op ())
-+ continue;
-+
-+ if (i0.get_dst_regno () != i1.get_src_regno ())
-+ continue;
-+
-+ intval = -i0.get_src_intval ();
-+ if (intval < -8 || intval > 7)
-+ continue;
-+
-+ /* is the next sub value in range? */
-+ if (lastsub == index + 3 && (lastsubval - intval < -8 || lastsubval -
intval > 7))
-+ continue;
-+ }
-+
-+ /* next insn must be the jump. */
-+ insn_info & i2 = infos[index + 1];
-+ if (!i2.is_jump ())
-+ continue;
-+
-+ rtx jmppattern = single_set (i2.get_insn ());
-+ if (!jmppattern)
-+ continue;
-+
-+ rtx jmpsrc = XEXP(jmppattern, 1);
-+ if (GET_CODE(jmpsrc) != IF_THEN_ELSE)
-+ continue;
-+
-+ rtx condition = XEXP(jmpsrc, 0);
-+ RTX_CODE code = GET_CODE(condition);
-+ if (code != EQ && code != NE)
-+ continue;
-+
-+ if (intval)
-+ {
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (),
intval));
-+
-+ rtx_insn * subinsn = make_insn_raw (gen_rtx_SET(copyreg, sub));
-+
-+ if (insn_invalid_p (subinsn, 0))
-+ continue;
-+
-+ /* delete move #x,dy. */
-+ SET_INSN_DELETED(i0.get_insn ())
-+ /* delete cmp dx,dy */
-+ SET_INSN_DELETED(i1.get_insn ());
-+ /* add a cmp #0 - to be removed in final() */
-+
-+ /* convert cmp/tst into sub */
-+ subinsn = emit_insn_before (PATTERN (subinsn), i1.get_insn ());
-+ i1.set_insn (subinsn);
-+
-+ rtx neu = gen_rtx_SET(cc0_rtx,
-+ gen_rtx_COMPARE (i1.get_mode (), copyreg, gen_rtx_CONST_INT (i1.get_mode (), 0)));
-+
-+ emit_insn_before (neu, i2.get_insn ());
-+
-+ log ("(c) const_cmp_to_sub replaced %s == %s (%d) with sub %d,%s\n",
reg_names[i1.get_dst_regno ()],
-+ reg_names[i0.get_dst_regno ()],
-+ -intval, -intval, reg_names[i1.get_dst_regno ()]);
-+
-+ if (index + 3 == lastsub)
-+ {
-+ /* patch previous sub - or even a compare. */
-+ insn_info & pp = infos[lastsub];
-+
-+ int diff = lastsubval - intval;
-+ rtx c = gen_rtx_CONST_INT (i1.get_mode (), diff);
-+
-+ if (pp.is_compare ())
-+ {
-+ /* still a compare with 0 -> insert the sub. */
-+ rtx copyreg = copy_reg (i1.get_dst_reg (), -1);
-+ /* create the sub statement. */
-+ rtx sub = gen_rtx_PLUS(i1.get_mode (), copyreg, c);
-+ rtx set = gen_rtx_SET(copyreg, sub);
-+ emit_insn_before (set, pp.get_insn ());
-+ }
-+ else
-+ {
-+ /* modify the sub. */
-+ XEXP(SET_SRC(PATTERN(pp.get_insn())), 1) = c;
-+ }
-+ }
-+
-+ lastsub = index;
-+ ++change_count;
-+ }
-+ }
-+#endif
-+ return change_count;
-+}
-+
-+/*
-+ * rare and only little gain - but :-)
-+ lea (-1,a0),a1
-+ add.l d1,a1
-+ subq.l #1,d1
-+ ->
-+ move.l a0,a1
-+ subq.l #1,d1
-+ add.l d1,a1
-+ */
-+static unsigned
-+opt_merge_add (void)
-+{
-+ unsigned change_count = 0;
-+ for (unsigned index = 0; index + 2 < infos.size (); ++index)
-+ {
-+ insn_info & ii0 = infos[index];
-+ insn_info & ii1 = infos[index + 1];
-+ insn_info & ii2 = infos[index + 2];
-+
-+ if (!ii2.is_dst_reg ())
-+ {
-+ index += 2;
-+ continue;
-+ }
-+
-+ if (!ii1.is_dst_reg ())
-+ {
-+ ++index;
-+ continue;
-+ }
-+
-+ if (!ii0.is_dst_reg () || ii0.get_src_op () != PLUS || ii1.get_src_op () != PLUS
|| ii2.get_src_op () != PLUS)
-+ continue;
-+
-+ if (!ii0.is_src_const () || !ii2.is_src_const () || ii0.get_src_intval () !=
ii2.get_src_intval ())
-+ continue;
-+
-+ if (ii0.get_dst_regno () != ii1.get_dst_regno () || ii1.get_src_regno () !=
ii2.get_dst_regno ())
-+ continue;
-+
-+ rtx_insn * insn1 = ii1.get_insn ();
-+
-+ CC_STATUS_INIT;
-+ NOTICE_UPDATE_CC(PATTERN (insn1), insn1);
-+ if (cc_status.value1 || cc_status.value2)
-+ continue;
-+
-+ log ("(m) %d: merge_add applied\n", index);
-+
-+ rtx_insn * insn0 = ii0.get_insn ();
-+ rtx set = PATTERN (insn0);
-+
-+ // convert lea (-1,a0),a1 into move.l a0,a1
-+ rtx_insn * newins0 = make_insn_raw (gen_rtx_SET(XEXP(set, 0), XEXP(XEXP(set, 1),
0)));
-+ add_insn_after (newins0, insn0, 0);
-+ SET_INSN_DELETED(insn0);
-+ // update infos accordingly
-+ ii0.plus_to_move (newins0);
-+
-+ rtx_insn * insn2 = ii2.get_insn ();
-+ rtx_insn * newins1 = make_insn_raw (PATTERN (insn1));
-+ add_insn_after (newins1, insn2, 0);
-+ SET_INSN_DELETED(insn1);
-+ ii1.swap_adds (newins1, ii2);
-+
-+ ++change_count;
-+ }
-+ return change_count;
-+}
-+
-+/* Update the insn_infos to 'know' the sp offset. */
-+static unsigned
-+track_sp ()
-+{
-+// reset visited flags - also check if sp is used as REG src.
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+
-+ // if sp is used as source, we cannot shrink the stack yet
-+ // too complicated
-+ if (ii.get_src_regno () == STACK_POINTER_REGNUM)
-+ return -1;
-+ }
-+
-+// add entry point
-+ std::set<unsigned> todo;
-+ todo.insert (0);
-+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = *todo.begin ();
-+ todo.erase (todo.begin ());
-+
-+ int sp_offset = infos[startpos].get_sp_offset ();
-+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () != IN_CODE)
-+ {
-+ ii.set_sp_offset (sp_offset);
-+ continue;
-+ }
-+
-+ // already visited? sp_offset must match
-+ if (ii.is_visited ())
-+ {
-+ if (ii.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
-+ break;
-+ }
-+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.set_sp_offset (sp_offset);
-+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end ()
&& i->first == k->first; ++i)
-+ {
-+ insn_info & ll = infos[i->second];
-+ if (ll.is_visited () && ll.get_sp_offset () != sp_offset)
-+ return E_SP_MISMATCH;
-+
-+ ll.set_sp_offset (sp_offset);
-+ todo.insert (i->second);
-+ }
-+ continue;
-+ }
-+
-+ // is sp modified directly
-+ if (ii.is_dst_reg () && ii.get_dst_regno () == STACK_POINTER_REGNUM)
-+ {
-+ // handle sp = sp + const_int
-+ if (!ii.get_src_reg () || ii.get_src_regno () != STACK_POINTER_REGNUM ||
ii.get_src_op () != PLUS)
-+ return E_SP_MISMATCH;
-+
-+ sp_offset = sp_offset + ii.get_src_intval ();
-+ continue;
-+ }
-+
-+ // handle dst mem autoinc
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () == STACK_POINTER_REGNUM
&& ii.get_dst_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_dst_autoinc ();
-+
-+ // handle src mem autoinc
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () == STACK_POINTER_REGNUM
&& ii.get_src_autoinc ())
-+ sp_offset += GET_MODE_SIZE(ii.get_mode()) * ii.get_src_autoinc ();
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+/* recursive function to patch stack pointer offsets. */
-+void
-+patch_sp (rtx x, int adjust, int spoffset)
-+{
-+ int code = GET_CODE(x);
-+ if (code == PLUS)
-+ {
-+ rtx a = XEXP(x, 0);
-+ rtx b = XEXP(x, 1);
-+ if (REG_P(a) && REGNO(a) == STACK_POINTER_REGNUM && GET_CODE(b) ==
CONST_INT)
-+ {
-+ if (INTVAL(b) > -spoffset)
-+ XEXP(x, 1) = gen_rtx_CONST_INT (GET_MODE(b), INTVAL(b) - adjust);
-+ return;
-+ }
-+ }
-+ const char *fmt = GET_RTX_FORMAT(code);
-+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-+ {
-+ if (fmt[i] == 'e')
-+ patch_sp (XEXP(x, i), adjust, spoffset);
-+ else if (fmt[i] == 'E')
-+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
-+ patch_sp (XVECEXP(x, i, j), adjust, spoffset);
-+ }
-+}
-+
-+/**
-+ * 1. scan for all used registers.
-+ * 2. scan the stack from for omittable push/pop
-+ * 3. adjust stack frame + insns referring to stack pointer
-+ * typical code:
-+ subq.l #4,sp
-+ movem.l #16190,-(sp)
-+ move.l 52(sp),d2
-+ move.l 56(sp),d3
-+
-+ * or
-+ link a5,#4
-+ movem.l #16190,-(sp)
-+ move.l 8(a5),d2
-+ move.l 12(a5),d3
-+ *
-+ * => with a5 check only prolog/epilog
-+ * => without a5 adjust insns referring sp if offset > startoffset + current sp
diff
-+ *
-+ * startvalue count(pushes)*4
-+ * newstartvalue = startvalue - omitted pushes
-+ */
-+static unsigned
-+opt_shrink_stack_frame (void)
-+{
-+ /* nothing to do. */
-+ if (!infos.size ())
-+ return 0;
-+
-+ /* needed to track sp correctly. */
-+ update_label2jump ();
-+ if (track_sp ())
-+ return 0; // do nothing on stack errors
-+
-+ std::vector<int> a5pos;
-+
-+ unsigned pos = 0;
-+ rtx_insn * insn = infos[pos].get_insn ();
-+ if (JUMP_P(insn)) /* return -> empty function*/
-+ return 0;
-+
-+ bool usea5 = false;
-+ int paramstart = 4;
-+ int a5offset = 0;
-+
-+ /*
-+ * Move prologue to temp.
-+ * Only register push and parallel insn unless its a link a5 are moved.
-+ */
-+ for (; pos < infos.size ();)
-+ {
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-+
-+ if (ii.in_proepi () != IN_PROLOGUE)
-+ break;
-+
-+ rtx pattern = PATTERN (insn);
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
-+ /* ignore link a5 */
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ {
-+ a5pos.push_back (pos);
-+ usea5 = true;
-+ set = XVECEXP(pattern, 0, 2);
-+ a5offset = INTVAL(XEXP(SET_SRC(set), 1));
-+ }
-+ ++pos;
-+ continue;
-+ }
-+ if (GET_CODE(pattern) != SET)
-+ {
-+ /* (set (mem:BLK (scratch) [0 A8]) (unspec:BLK [ ...)) */
-+ if (MEM_P(SET_DEST(pattern)) && GET_CODE(SET_SRC(pattern)) == UNSPEC)
-+ a5pos.push_back (pos);
-+ ++pos;
-+ continue;
-+ }
-+
-+ /* move only the push statements. */
-+ rtx src = SET_SRC(pattern);
-+ rtx dest = SET_DEST(pattern);
-+ if (REG_P(src))
-+ {
-+ if (MEM_P(dest))
-+ {
-+ rtx predec = XEXP(dest, 0);
-+ if (GET_CODE(predec) == PRE_DEC)
-+ {
-+ rtx reg = XEXP(predec, 0);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
-+ {
-+ ii.mark_stack ();
-+ }
-+ }
-+ }
-+ }
-+ else if (GET_CODE(src) == PLUS && REG_P(dest) && REGNO(dest) ==
STACK_POINTER_REGNUM)
-+ {
-+ /* check for stack variables. */
-+ rtx reg = XEXP(src, 0);
-+ rtx cx = XEXP(src, 1);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM &&
CONST_INT_P(cx))
-+ paramstart -= INTVAL(cx);
-+ }
-+
-+ if (++pos >= infos.size ())
-+ {
-+ return 0;
-+ }
-+ }
-+
-+ if (pos == 0)
-+ return 0;
-+
-+ unsigned prologueend = pos;
-+
-+ /* search epilogues - there can be multiple epilogues. */
-+ while (pos < infos.size ())
-+ {
-+ while (pos < infos.size ())
-+ {
-+ if (infos[pos].in_proepi () != IN_CODE)
-+ break;
-+ ++pos;
-+ }
-+
-+ /* move epilogues away. */
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & ii = infos[pos];
-+ insn = ii.get_insn ();
-+ if (JUMP_P(insn) || LABEL_P(insn) || ii.in_proepi () == IN_CODE)
-+ break;
-+
-+ /* omit the frame pointer a5. */
-+ rtx pattern = PATTERN (insn);
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ ii.mark_stack ();
-+ /* unlink is last. */
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ {
-+ a5pos.push_back (pos);
-+ break;
-+ }
-+
-+ }
-+ else if (GET_CODE(pattern) == SET)
-+ {
-+ /* check for move (a7+), x */
-+ rtx src = SET_SRC(pattern);
-+ rtx dst = SET_DEST(pattern);
-+ if (REG_P(dst))
-+ {
-+ if (MEM_P(src))
-+ {
-+ rtx postinc = XEXP(src, 0);
-+ if (GET_CODE(postinc) == POST_INC)
-+ {
-+ rtx reg = XEXP(postinc, 0);
-+ if (REG_P(reg) && REGNO(reg) == STACK_POINTER_REGNUM)
-+ ii.mark_stack ();
-+ }
-+ else if (GET_CODE(postinc) == PLUS)
-+ {
-+ rtx a5 = XEXP(postinc, 0);
-+ if (REG_P(a5) && REGNO(a5) == FRAME_POINTER_REGNUM)
-+ ii.mark_stack ();
-+ }
-+ }
-+ }
-+ }
-+ }
-+ ++pos;
-+ }
-+ /* gather usage stats without prologue/epilogue */
-+ insn_info ii;
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & jj = infos[i];
-+ if (jj.in_proepi () != IN_CODE)
-+ continue;
-+
-+ ii.or_use (jj);
-+ }
-+ unsigned freemask = ~ii.get_use () & 0x7fff;
-+
-+ rtx a7 = gen_raw_REG (SImode, STACK_POINTER_REGNUM);
-+ rtx a5 = gen_raw_REG (SImode, FRAME_POINTER_REGNUM);
-+
-+ unsigned changed = 0;
-+ unsigned adjust = 0;
-+ unsigned regs_seen = 0;
-+ unsigned regs_total_size = 0;
-+ /* now all push/pop insns are in temp. */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (!ii.is_stack ())
-+ continue;
-+
-+ insn = ii.get_insn ();
-+ rtx pattern = PATTERN (insn);
-+ /* check the pushed regs, either a vector or single statements */
-+ if (GET_CODE(pattern) == PARALLEL)
-+ {
-+ // do not touch the frame pointer parallel insn.
-+ rtx set = XVECEXP(pattern, 0, 0);
-+ rtx dst = SET_DEST(set);
-+ if (REG_P(dst) && REGNO(dst) == FRAME_POINTER_REGNUM)
-+ continue;
-+
-+ if (ii.in_proepi () == IN_EPILOGUE)
-+ ii.set_proepi (IN_EPILOGUE_PARALLEL_POP);
-+
-+ regs_seen = 0;
-+ regs_total_size = 0;
-+ std::vector<rtx> regs;
-+ std::vector<rtx> clobbers;
-+ for (int j = 0; j < XVECLEN(pattern, 0); ++j)
-+ {
-+ rtx set = XVECEXP(pattern, 0, j);
-+ if (GET_CODE(set) == CLOBBER)
-+ {
-+ clobbers.push_back (set);
-+ continue;
-+ }
-+ rtx dst = SET_DEST(set);
-+ rtx src = SET_SRC(set);
-+ rtx reg;
-+ if (MEM_P(src))
-+ reg = dst;
-+ else if (MEM_P(dst))
-+ reg = src;
-+ else
-+ continue;
-+
-+ if (i < prologueend)
-+ paramstart += 4;
-+ unsigned regbit = 1 << REGNO(reg);
-+
-+ ++regs_seen;
-+ if (freemask & regbit)
-+ {
-+ log (i < prologueend ? "(f) remove push for %s\n" : "(f) remove
pop for %s\n",
-+ reg_names[REGNO(reg)]);
-+ if (i < prologueend)
-+ adjust += GET_MODE_SIZE(GET_MODE(reg));
-+ }
-+ else
-+ {
-+ regs_total_size += GET_MODE_SIZE(GET_MODE(reg));
-+ regs.push_back (copy_reg (reg, -1));
-+ }
-+ }
-+
-+ /* add room for add.
-+ * push is always using -(a7) addressing.
-+ * If a5 is used a movem offset(a5) is generated to pop saved registers..
-+ * Otherwise a7 is used and with (a7)+ addressing.
-+ */
-+ int add1 = i < prologueend || !usea5 ? 1 : 0;
-+ if (regs.size () < regs_seen)
-+ {
-+ log ("(f) shrinking stack frame from %d to %d\n", regs_seen, regs.size
());
-+ if (regs.size () <= 2)
-+ {
-+ changed = 1;
-+ for (unsigned k = 0; k < regs.size (); ++k)
-+ {
-+ rtx reg = regs[k];
-+ if (i < prologueend)
-+ {
-+ /* push */
-+ rtx dec = gen_rtx_PRE_DEC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
dec);
-+ rtx set = gen_rtx_SET(mem, reg);
-+ emit_insn_after (set, insn);
-+ }
-+ else
-+ {
-+ /* pop */
-+ rtx dec = gen_rtx_POST_INC(REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, a7);
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
dec);
-+ rtx set = gen_rtx_SET(reg, mem);
-+ emit_insn_before (set, insn);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (regs.size () + add1 +
clobbers.size ()));
-+ rtx plus;
-+
-+ int x = 0;
-+ for (unsigned k = 0; k < regs.size (); ++k)
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+
-+ unsigned l = 0;
-+ /* no add if a5 is used with pop */
-+ if (add1)
-+ {
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, i < prologueend ?
-x : x));
-+ XVECEXP(parallel, 0, l) = gen_rtx_SET(a7, plus);
-+ ++l;
-+ }
-+
-+ if (i >= prologueend)
-+ x = usea5 ? -x : 0;
-+
-+ for (unsigned k = 0; k < regs.size (); ++k, ++l)
-+ {
-+ if (i < prologueend)
-+ {
-+ /* push */
-+ plus = gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, -x));
-+ x -= REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode : SImode,
plus);
-+ rtx set = gen_rtx_SET(mem, regs[k]);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ else
-+ {
-+ /* pop */
-+ if (usea5)
-+ {
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ plus = gen_rtx_PLUS(SImode, a5, gen_rtx_CONST_INT (SImode, a5offset + x));
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ else
-+ {
-+ plus = x ? gen_rtx_PLUS(SImode, a7, gen_rtx_CONST_INT (SImode, x)) : a7;
-+ x += REGNO(regs[k]) > STACK_POINTER_REGNUM ? 12 : 4;
-+ rtx mem = gen_rtx_MEM (REGNO(regs[k]) > STACK_POINTER_REGNUM ? XFmode :
SImode, plus);
-+ rtx set = gen_rtx_SET(regs[k], mem);
-+ XVECEXP(parallel, 0, l) = set;
-+ }
-+ }
-+ }
-+
-+ for (unsigned k = 0; k < clobbers.size (); ++k, ++l)
-+ {
-+ rtx clobber = clobbers[k];
-+ XVECEXP(parallel, 0, l) = clobber;
-+ }
-+
-+ rtx_insn * neu;
-+ if (i < prologueend)
-+ neu = emit_insn_after (parallel, insn);
-+ else
-+ neu = emit_insn_before (parallel, insn);
-+ ii.set_insn (neu);
-+ }
-+ SET_INSN_DELETED(insn);
-+ changed = 1;
-+ }
-+ }
-+ else
-+ {
-+ rtx set = PATTERN (insn);
-+
-+ if (i < prologueend)
-+ {
-+ /* move x,-(a7). */
-+ rtx src = SET_SRC(set);
-+ paramstart += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-+ unsigned regbit = 1 << REGNO(src);
-+ if (freemask & regbit)
-+ {
-+ adjust += REGNO(src) > STACK_POINTER_REGNUM ? 12 : 4;
-+ log ("(f) remove push for %s\n", reg_names[REGNO(src)]);
-+ SET_INSN_DELETED(insn);
-+ ++changed;
-+ }
-+ }
-+ else
-+ {
-+ /* move (a7)+,x */
-+ rtx dst = SET_DEST(set);
-+ unsigned regbit = 1 << REGNO(dst);
-+ if (freemask & regbit)
-+ {
-+ log ("(f) remove pop for %s\n", reg_names[REGNO(dst)]);
-+ SET_INSN_DELETED(insn);
-+ ++changed;
-+ }
-+ }
-+ }
-+ }
-+
-+ /* fix sp offsets. */
-+ if (!usea5 && adjust)
-+ {
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () != IN_CODE)
-+ continue;
-+
-+ rtx pattern = single_set (ii.get_insn ());
-+ if (pattern)
-+ patch_sp (pattern, adjust, ii.get_sp_offset ());
-+ }
-+ }
-+
-+ if (usea5 && a5offset == -4)
-+ {
-+ /* for now only drop the frame pointer if it's not used.
-+ * Needs tracking of the sp to adjust the offsets.
-+ */
-+ if (freemask & (1 << FRAME_POINTER_REGNUM))
-+ {
-+ log ("(f) dropping unused frame pointer\n");
-+ for (std::vector<int>::reverse_iterator i = a5pos.rbegin (); i != a5pos.rend
(); ++i)
-+ {
-+ int index = *i;
-+ SET_INSN_DELETED(infos[index].get_insn ());
-+
-+ // move to last insn in epilogue
-+ while (index - 1 > 0 && infos[index - 1].in_proepi () >=
IN_EPILOGUE)
-+ --index;
-+
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () >= IN_EPILOGUE && ii.get_sp_offset () != 0)
-+ {
-+ log ("(f) adjusting exit sp\n");
-+ rtx pattern = gen_rtx_SET(
-+ a7, gen_rtx_PLUS (SImode, a7, gen_rtx_CONST_INT (SImode, -ii.get_sp_offset
())));
-+ emit_insn_before (pattern, ii.get_insn ());
-+ }
-+ }
-+
-+ /* convert all parameter accesses via a5 into a7. */
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+ if (ii.get_myuse () & (1 << FRAME_POINTER_REGNUM))
-+ {
-+ ii.a5_to_a7 (a7);
-+ if (regs_seen && ii.in_proepi () == IN_EPILOGUE_PARALLEL_POP)
-+ {
-+ // exit sp insn needs an +
-+ rtx pattern = PATTERN (ii.get_insn ());
-+ unsigned sz = XVECLEN(pattern, 0);
-+
-+ rtx parallel = gen_rtx_PARALLEL(VOIDmode, rtvec_alloc (sz + 1));
-+ unsigned n = 0;
-+ for (unsigned j = 0; j < sz; ++j)
-+ {
-+ rtx set = XVECEXP(pattern, 0, j);
-+ rtx reg = SET_DEST(set);
-+ rtx mem = SET_SRC(set);
-+ rtx plus = XEXP(mem, 0);
-+ if (n)
-+ {
-+ XEXP(plus, 1) = gen_rtx_CONST_INT (SImode, n);
-+ }
-+ else
-+ {
-+ XEXP(mem, 0) = XEXP(plus, 0);
-+ }
-+ n += GET_MODE_SIZE(GET_MODE(reg));
-+ XVECEXP(parallel, 0, j + 1) = set;
-+ }
-+
-+ rtx a = copy_reg (a7, -1);
-+ a->frame_related = 1;
-+ rtx plus = gen_rtx_PLUS(SImode, a, gen_rtx_CONST_INT (SImode,
regs_total_size));
-+ rtx set = gen_rtx_SET(a, plus);
-+ XVECEXP(parallel, 0, 0) = set;
-+ SET_INSN_DELETED(ii.get_insn ());
-+ ii.set_insn (emit_insn_after (parallel, ii.get_insn ()));
-+ }
-+ }
-+
-+ ii.unset (FRAME_POINTER_REGNUM);
-+ }
-+
-+ update_insn2index ();
-+ ++changed;
-+ }
-+ }
-+
-+ return changed;
-+}
-+
-+/* Update the insn_infos to 'know' the value for each register.
-+ *
-+ * assignments to registers are optimized by knowing the value. If the same value is
assigned, omit that insn.
-+ *
-+ * I'm tracking
-+ *
-+ * rtx - the value
-+ *
-+ * mask - the referenced registers in the value, 0 means that rtx is const, with
baserel a4 is not tracked
-+ *
-+ * if there is a value for the referenced register(s), the value is extended
-+ *
-+ * e.g.
-+ *
-+ * ; line 2
-+ * move.l 12(a7),a0
-+ *
-+ * -> rtx = mem(plus(a7, 12)); 0x8000
-+ *
-+ * ; line 10
-+ * move.l 4(a0),d0
-+ *
-+ * -> rtx = mem(plus(mem(plus(a7, 12)), 4)); 0x8000; extended with value from a0,
thus a7 is used only
-+ *
-+ * ;15
-+ * lea _label,a1
-+ *
-+ * -> rtx = symbol_ref(_label) ; 0x0000 == const
-+ *
-+ * on jumps the current state is duplicated and merged at the given label
-+ *
-+ * on merge only identical info is kept, rest is discarded
-+ *
-+ * for each insn for all defined regs the value and mask is discarded before a new
value is set.
-+ *
-+ * for each insn which is writing to memory, all non const values are discarded.
-+ *
-+ *
-+ * after the track info is complete, each insn setting a register is evaluated against
the track info.
-+ *
-+ * now redundant loads are found and eliminated
-+ *
-+ */
-+
-+static unsigned
-+track_regs ()
-+{
-+// reset visited flags
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+ ii.clear_visited ();
-+ ii.set_sp_offset (0);
-+ }
-+
-+ update_label2jump ();
-+
-+// add entry point
-+ std::multimap<unsigned, track_var *> todo;
-+ todo.insert (std::make_pair (0, new track_var ()));
-+
-+ while (todo.begin () != todo.end ())
-+ {
-+ unsigned startpos = todo.begin ()->first;
-+ track_var * const track = todo.begin ()->second;
-+ todo.erase (todo.begin ());
-+
-+ for (unsigned index = startpos; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ // already visited?
-+ if (index != startpos && ii.is_visited () && ii.get_track_var
()->no_merge_needed (track))
-+ break;
-+
-+ // only keep common values at labels
-+ if (ii.is_label ())
-+ {
-+ if (ii.is_visited ())
-+ {
-+ ii.get_track_var ()->merge (track, index);
-+ }
-+ else
-+ {
-+ ii.get_track_var ()->assign (track);
-+ ii.mark_visited ();
-+ }
-+ continue;
-+ }
-+
-+ // mark current insn_info and set sp_offset
-+ ii.mark_visited ();
-+ ii.get_track_var ()->assign (track);
-+
-+ if (ii.is_compare ())
-+ continue;
-+
-+ unsigned def = ii.get_def () & 0xffffff;
-+ if (def)
-+ {
-+ // more than one register set? or mask from clobber?
-+ if (((def - 1) & def) || !ii.get_dst_reg ())
-+ track->clear_for_mask (def, index);
-+ }
-+ // do not clear if self assigned
-+ int dregno = ii.get_dst_regno ();
-+ if (dregno != ii.get_src_regno ())
-+ track->clear (ii.get_mode (), dregno, index);
-+
-+ if (ii.is_call ())
-+ {
-+ track->clear_aftercall (index);
-+ continue;
-+ }
-+
-+ rtx set = single_set (ii.get_insn ());
-+
-+ // add all referred labels
-+ if (ii.is_jump ())
-+ {
-+ if (ANY_RETURN_P(ii.get_insn ()))
-+ break;
-+
-+ for (j2l_iterator i = jump2label.find (index), k = i; i != jump2label.end ()
&& i->first == k->first; ++i)
-+ todo.insert (std::make_pair (i->second, new track_var (track)));
-+
-+ if (set && GET_CODE(SET_SRC(set)) == IF_THEN_ELSE)
-+ continue;
-+
-+ // unconditional jump
-+ break;
-+ }
-+
-+ if (!set || !ii.get_def ())
-+ continue;
-+
-+ if (dregno < 0)
-+ {
-+ track->invalidate_mem (SET_DEST(set));
-+ continue;
-+ }
-+
-+ // operation, autoinf or more than one register used: can't cache
-+ if (ii.get_src_op () || ii.get_src_autoinc () || ((ii.get_myuse () - 1) &
ii.get_myuse ()))
-+ continue;
-+
-+ rtx src = SET_SRC(set);
-+ if (ii.is_src_mem () && src->volatil)
-+ continue;
-+
-+ track->set (ii.get_mode (), dregno, src, index);
-+ }
-+ delete track;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ * Some optimizations (e.g. propagate_moves) might result into an unused assignment
behind the loop.
-+ * delete those insns.
-+ */
-+static unsigned
-+opt_elim_dead_assign (int blocked_regno)
-+{
-+ track_regs ();
-+
-+ unsigned change_count = 0;
-+ for (int index = infos.size () - 1; index >= 0; --index)
-+ {
-+ insn_info & ii = infos[index];
-+ if (ii.in_proepi () || !ii.get_dst_reg () || ii.is_compare ())
-+ continue;
-+
-+ rtx_insn * insn = ii.get_insn ();
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ if (ii.get_dst_reg () && REG_NREGS(ii.get_dst_reg ()) == 1 &&
ii.get_dst_regno () != blocked_regno
-+ && is_reg_dead (ii.get_dst_regno (), index))
-+ {
-+ log ("(e) %d: eliminate dead assign to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ // check for redundant load
-+ if (ii.get_src_op () == 0 && ii.get_dst_reg () && ii.get_dst_regno
() != blocked_regno
-+ && (!ii.is_myuse (ii.get_dst_regno ()) || ii.get_dst_regno () ==
ii.get_src_regno ()))
-+ {
-+ track_var * track = ii.get_track_var ();
-+
-+ rtx src = SET_SRC(set);
-+ if (track->equals (ii.get_dst_regno (), src))
-+ {
-+ log ("(e) %d: eliminate redundant load to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ if (ii.get_src_reg () && track->equals (ii.get_src_regno (),
SET_DEST(set)))
-+ {
-+ log ("(e) %d: eliminate redundant reverse load to %s\n", index,
reg_names[ii.get_dst_regno ()]);
-+ SET_INSN_DELETED(insn);
-+ ++change_count;
-+ continue;
-+ }
-+
-+ // is there a register holding that value?
-+ if (!ii.get_src_reg ())
-+ {
-+ int aliasRegno = track->find_alias (src);
-+ if (aliasRegno >= 0 && aliasRegno != ii.get_dst_regno ())
-+ {
-+ log ("(e) %d: replace load with %s\n", index, reg_names[aliasRegno]);
-+ validate_change (ii.get_insn (), &SET_SRC(set), gen_rtx_REG (ii.get_mode (),
aliasRegno), 0);
-+ ++change_count;
-+ }
-+ }
-+ }
-+ }
-+ return change_count;
-+}
-+
-+/*
-+ * Convert a series of move into absolute address into register based moves.
-+ */
-+static unsigned
-+opt_absolute (void)
-+{
-+ unsigned change_count = 0;
-+
-+ for (unsigned i = 0; i < infos.size (); ++i)
-+ {
-+ insn_info & ii = infos[i];
-+
-+ if (ii.is_compare ())
-+ continue;
-+
-+ if (ii.get_src_op () && ii.is_src_ee () && !ii.get_src_intval ())
-+ continue;
-+
-+ bool is_dst = ii.is_dst_mem () && (ii.has_dst_addr () || ii.get_dst_symbol
()) && !ii.has_dst_memreg ();
-+ bool is_src = ii.is_src_mem () && (ii.has_src_addr () || ii.get_src_symbol
()) && !ii.has_src_memreg ();
-+
-+ if (!is_dst && !is_src)
-+ continue;
-+
-+ if (ii.get_mode () == VOIDmode)
-+ continue;
-+
-+ unsigned freemask = ~(ii.get_use () | ii.get_def ()) & 0x7f00 &
usable_regs;
-+ if (!freemask)
-+ continue;
-+
-+ rtx with_symbol = is_dst ? ii.get_dst_symbol () : ii.get_src_symbol ();
-+
-+ std::vector<unsigned> found;
-+ found.push_back (i);
-+ int base = ii.get_dst_mem_addr ();
-+ int max = base;
-+ unsigned j = i + 1;
-+ for (; j < infos.size (); ++j)
-+ {
-+ insn_info & jj = infos[j];
-+ /* TODO: continue also at jump target */
-+ if (jj.is_jump ())
-+ continue;
-+ /* TODO: check if label is visited only from jump targets from herein. then the label
is ok. */
-+ if (jj.is_label ())
-+ break;
-+
-+ unsigned tempmask = freemask & ~(jj.get_use () | jj.get_def ());
-+ if (!tempmask)
-+ break;
-+ freemask = tempmask;
-+
-+ if (jj.get_mode () == VOIDmode || jj.is_compare ())
-+ continue;
-+
-+ if (jj.get_src_op () && jj.is_src_ee () && !jj.get_src_intval ())
-+ continue;
-+
-+ bool j_dst = jj.is_dst_mem () && (jj.has_dst_addr () || jj.get_dst_symbol ())
&& !jj.has_dst_memreg ()
-+ && jj.get_dst_symbol () == with_symbol;
-+ bool j_src = jj.is_src_mem () && (jj.has_src_addr () || jj.get_src_symbol ())
&& !jj.has_src_memreg ()
-+ && jj.get_src_symbol () == with_symbol;
-+
-+ /* exclude operations on that symbol. */
-+
-+ if (j_dst)
-+ {
-+ int addr = jj.get_dst_mem_addr ();
-+ if (addr < base)
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ if (j_src)
-+ {
-+ int addr = jj.get_src_mem_addr ();
-+ if (addr < base)
-+ {
-+ if (max - addr <= 0x7ffe)
-+ {
-+ base = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ else if (addr - base <= 0x7ffe)
-+ {
-+ if (addr > max)
-+ max = addr;
-+ found.push_back (j);
-+ continue;
-+ }
-+ }
-+ }
-+
-+ if (freemask && found.size () > 2)
-+ {
-+ unsigned regno = bit2regno (freemask);
-+ /* check again. */
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();)
-+ {
-+ insn_info & kk = infos[*k];
-+ bool k_dst = kk.is_dst_mem () && (kk.has_dst_addr () || kk.get_dst_symbol
()) && !kk.has_dst_memreg ()
-+ && kk.get_dst_symbol () == with_symbol;
-+ bool k_src = kk.is_src_mem () && (kk.has_src_addr () || kk.get_src_symbol
()) && !kk.has_src_memreg ()
-+ && kk.get_src_symbol () == with_symbol;
-+ if (k_dst && kk.get_dst_mem_addr () - base > 0x7ffc)
-+ k = found.erase (k);
-+ else if (k_src && kk.get_src_mem_addr () - base > 0x7ffc)
-+ k = found.erase (k);
-+ else if (insn_invalid_p (make_insn_raw (kk.make_absolute2base (regno, base,
with_symbol, false)), 0))
-+ k = found.erase (k);
-+ else
-+ ++k;
-+ }
-+ }
-+ if (freemask && found.size () > 2)
-+ {
-+ unsigned regno = bit2regno (freemask);
-+ if (with_symbol)
-+ log ("(b) modifying %d symbol addresses for %s using %s\n", found.size
(),
-+ with_symbol->u.block_sym.fld[0].rt_str, reg_names[regno]);
-+ else
-+ log ("(b) modifying %d absolute addresses using %s\n", found.size (),
reg_names[regno]);
-+
-+ unsigned current_use = ii.get_use ();
-+
-+ for (std::vector<unsigned>::iterator k = found.begin (); k != found.end ();
++k)
-+ {
-+ insn_info & kk = infos[*k];
-+ kk.absolute2base (regno, base, with_symbol);
-+ insn_invalid_p (kk.get_insn (), 0);
-+ }
-+
-+ // load base into reg
-+ rtx lea;
-+
-+ if (with_symbol)
-+ {
-+ if (base)
-+ lea = gen_rtx_SET(
-+ gen_raw_REG (SImode, regno),
-+ gen_rtx_CONST (SImode, gen_rtx_PLUS (SImode, with_symbol, gen_rtx_CONST_INT
(SImode, base))));
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), with_symbol);
-+ }
-+ else
-+ lea = gen_rtx_SET(gen_raw_REG (SImode, regno), gen_rtx_CONST_INT (SImode, base));
-+ rtx_insn * insn = emit_insn_before (lea, ii.get_insn ());
-+ insn_info nn (insn);
-+ nn.set_use (current_use);
-+ nn.scan ();
-+ nn.fledder (lea);
-+ nn.mark_def (regno);
-+ infos.insert (infos.begin () + i, nn);
-+
-+ /* mark until last hit is found. */
-+ for (unsigned k = i + 1; k < infos.size (); ++k)
-+ {
-+ infos[k].mark_use (regno);
-+ if (k == *found.rbegin ())
-+ break;
-+ }
-+ ++change_count;
-+ --i;
-+ }
-+ }
-+
-+ if (change_count)
-+ update_insn2index ();
-+
-+ return change_count;
-+}
-+
-+static int
-+try_auto_inc (unsigned index, insn_info & ii, rtx reg)
-+{
-+ int const regno = REGNO(reg);
-+ unsigned size = GET_MODE_SIZE(ii.get_mode ());
-+ if (size > 4)
-+ return 0;
-+
-+// log ("starting auto_inc search for %s at %d\n", reg_names[regno],
index);
-+
-+ // track all fixups to modify
-+ std::set<unsigned> fixups;
-+
-+ // all paths to check
-+ std::vector<unsigned> todo;
-+ todo.push_back (index + 1);
-+
-+ bool match_size = false;
-+ std::set<unsigned> visited;
-+ while (todo.size () > 0)
-+ {
-+ unsigned pos = todo[todo.size () - 1];
-+ todo.pop_back ();
-+
-+ if (pos == index)
-+ return 0;
-+
-+ if (visited.find (pos) != visited.end ())
-+ continue;
-+ visited.insert (pos);
-+
-+ for (; pos < infos.size (); ++pos)
-+ {
-+ insn_info & jj = infos[pos];
-+
-+ // check all jumps labels for register usage
-+ if (jj.is_label ())
-+ {
-+ for (l2j_iterator j = label2jump.find (jj.get_insn ()->u2.insn_uid), k = j;
-+ j != label2jump.end () && j->first == k->first; ++j)
-+ {
-+ insn_info * ll = insn2info.find (j->second)->second;
-+ if (ll->is_use (regno))
-+ return 0;
-+ }
-+ break;
-+ }
-+
-+ // break if no longer used
-+ if (!jj.is_use (regno))
-+ break;
-+
-+ if (jj.in_proepi ())
-+ return 0;
-+
-+ // add all labels
-+ if (jj.is_jump ())
-+ {
-+ for (j2l_iterator j = jump2label.find (pos), k = j; j != jump2label.end ()
&& j->first == k->first; ++j)
-+ todo.push_back (j->second);
-+ continue;
-+ }
-+
-+ // not used directly
-+ if (!jj.is_myuse (regno))
-+ continue;
-+
-+ // can't fixup such kind of insn (yet)
-+ if (single_set (jj.get_insn ()) == 0)
-+ return 0;
-+
-+ // if reg is src reg, op must be add and addend must be large enough
-+ bool fix = false;
-+ if (jj.get_src_mem_regno () == regno)
-+ {
-+ if (jj.get_dst_regno () == regno)
-+ return 0;
-+
-+ if (jj.get_src_mem_addr () < size)
-+ return 0;
-+
-+ if (jj.get_src_mem_addr () == size)
-+ match_size = true;
-+
-+ fix = true;
-+ }
-+ if (jj.get_dst_mem_regno () == regno)
-+ {
-+ if (jj.get_src_regno () == regno)
-+ return 0;
-+
-+ if (jj.get_dst_mem_addr () < size)
-+ return 0;
-+
-+ if (jj.get_dst_mem_addr () == size)
-+ match_size = true;
-+
-+ fix = true;
-+ }
-+
-+ if (!fix)
-+ return 0;
-+
-+ fixups.insert (pos);
-+
-+ // done if this is an add
-+ if (ii.is_def (regno))
-+ break;
-+ }
-+ }
-+
-+ if (!match_size || !fixups.size ())
-+ return 0;
-+
-+ if (!ii.make_post_inc (regno))
-+ return 0;
-+
-+ log ("(i) auto_inc for %s at %d - %d fixups\n", reg_names[regno], index,
fixups.size ());
-+
-+ // fix all offsets / adds
-+ for (std::set<unsigned>::iterator k = fixups.begin (); k != fixups.end (); ++k)
-+ {
-+// log ("(i) fixup at %d\n", *k);
-+ insn_info & kk = infos[*k];
-+ kk.auto_inc_fixup (regno, size);
-+ }
-+ return 1;
-+}
-+
-+/*
-+ * Convert a series of reg with offset ( (ax), 4(ax), 8(ax), ...) into autoincx ( (ax+),
(ax+), (ax+), ...)
-+ *
-+ * 1. search a mem(reg) without offset and either src or dst is using that reg
-+ * 2. follow paths until reg is dead
-+ * 3. if there is another mem(reg) with offset check that
-+ * a) offset fits last mode size
-+ * b) all remaining insn using that reg can be updated by
-+ * i) decrement the offset
-+ * ii) decrement the add value
-+ */
-+static unsigned
-+opt_autoinc ()
-+{
-+ unsigned change_count = 0;
-+
-+ update_label2jump ();
-+
-+ for (unsigned index = 0; index < infos.size (); ++index)
-+ {
-+ insn_info & ii = infos[index];
-+
-+ if (ii.in_proepi ())
-+ continue;
-+
-+ if (!INSN_P(ii.get_insn ()))
-+ continue;
-+
-+// // more than one reg used
-+// if (ii.get_myuse () & (ii.get_myuse () - 1))
-+// continue;
-+
-+// // don't if fp regs are touched
-+// if ((ii.get_myuse () & 0xff0000))
-+// continue;
-+
-+ if (ii.is_src_mem () && ii.get_src_mem_regno () >= 8 &&
!ii.get_src_mem_addr () && !ii.get_src_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () &&
ii.get_src_mem_regno () != ii.get_dst_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_src_mem_reg ());
-+
-+ if (ii.is_dst_mem () && ii.get_dst_mem_regno () >= 8 &&
!ii.get_dst_intval () && !ii.get_dst_autoinc ()
-+ && ii.get_src_mem_regno () != ii.get_dst_mem_regno () &&
ii.get_src_regno () != ii.get_dst_mem_regno ())
-+ change_count += try_auto_inc (index, ii, ii.get_dst_mem_reg ());
-+
-+ }
-+
-+ return change_count;
-+}
-+
-+namespace
-+{
-+
-+ const pass_data pass_data_bbb_optimizations =
-+ { RTL_PASS, /* type */
-+ "bebbo's-optimizers", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_optimizations : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_optimizations (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_optimizations, ctxt), pp (0)
-+ {
-+ }
-+
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ if (!string_bbb_opts)
-+ string_bbb_opts = "+";
-+
-+ return TARGET_AMIGA && optimize > 0 && string_bbb_opts
&& !strchr (string_bbb_opts, '-');
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_optimizations ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ pass_bbb_optimizations * bbb = new pass_bbb_optimizations (m_ctxt);
-+ bbb->pp = pp + 1;
-+ return bbb;
-+ }
-+
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_optimizations (void);
-+ };
-+// class pass_bbb_optimizations
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_optimizations::execute_bbb_optimizations (void)
-+ {
-+ dump_reg_track = strchr (string_bbb_opts, 'R') != 0;
-+ be_very_verbose = strchr (string_bbb_opts, 'V') != 0;
-+ be_verbose = strchr (string_bbb_opts, 'v') != 0;
-+ if (be_verbose && be_very_verbose)
-+ ++be_very_verbose;
-+ if (be_very_verbose)
-+ be_verbose = true;
-+
-+ bool do_commute_add_move = strchr (string_bbb_opts, 'a') || strchr
(string_bbb_opts, '+');
-+ bool do_absolute = strchr (string_bbb_opts, 'b') || strchr (string_bbb_opts,
'+');
-+ bool do_const_cmp_to_sub = strchr (string_bbb_opts, 'c') || strchr
(string_bbb_opts, '+');
-+ bool do_elim_dead_assign = strchr (string_bbb_opts, 'e') || strchr
(string_bbb_opts, '+');
-+ bool do_shrink_stack_frame = strchr (string_bbb_opts, 'f') || strchr
(string_bbb_opts, '+');
-+ bool do_autoinc = strchr (string_bbb_opts, 'i') || strchr (string_bbb_opts,
'+');
-+ bool do_merge_add = strchr (string_bbb_opts, 'm') || strchr
(string_bbb_opts, '+');
-+ bool do_propagate_moves = strchr (string_bbb_opts, 'p') || strchr
(string_bbb_opts, '+');
-+ bool do_bb_reg_rename = strchr (string_bbb_opts, 'r') || strchr
(string_bbb_opts, '+');
-+ bool do_opt_strcpy = strchr (string_bbb_opts, 's') || strchr
(string_bbb_opts, '+');
-+
-+ if (be_very_verbose)
-+ log ("ENTER\n");
-+
-+ unsigned r = update_insns ();
-+ if (!r)
-+ {
-+ for (;;)
-+ {
-+ int done = 1;
-+ if (do_opt_strcpy && opt_strcpy ())
-+ done = 0, update_insns ();
-+
-+ if (do_commute_add_move && opt_commute_add_move ())
-+ done = 0, update_insns ();
-+
-+ if (do_propagate_moves && opt_propagate_moves ())
-+ done = 0, update_insns ();
-+
-+ if (do_const_cmp_to_sub && opt_const_cmp_to_sub ())
-+ done = 0, update_insns ();
-+
-+ if (do_merge_add && opt_merge_add ())
-+ done = 0;
-+
-+ if (do_elim_dead_assign && opt_elim_dead_assign (STACK_POINTER_REGNUM))
-+ done = 0, update_insns ();
-+
-+ if (do_absolute && opt_absolute ())
-+ done = 0, update_insns ();
-+
-+ if (do_autoinc && opt_autoinc ())
-+ done = 0, update_insns ();
-+
-+ if (do_bb_reg_rename)
-+ {
-+ while (opt_reg_rename ())
-+ {
-+ update_insns ();
-+ done = 0;
-+ }
-+ }
-+
-+ if (done)
-+ break;
-+ }
-+
-+ if (do_shrink_stack_frame)
-+ {
-+ if (opt_shrink_stack_frame ())
-+ update_insns ();
-+ }
-+
-+ /* elim stack pointer stuff last. */
-+ if (do_elim_dead_assign)
-+ opt_elim_dead_assign (FIRST_PSEUDO_REGISTER);
-+ }
-+ if (r && be_verbose)
-+ log ("no bbb optimization code %d\n", r);
-+
-+ if (strchr (string_bbb_opts, 'X') || strchr (string_bbb_opts, 'x'))
-+ dump_insns ("bbb", strchr (string_bbb_opts, 'X'));
-+
-+ if (dump_reg_track)
-+ {
-+ update_insns ();
-+ track_regs ();
-+ }
-+
-+ return r;
-+ }
-+
-+} // anon namespace
-+
-+rtl_opt_pass *
-+make_pass_bbb_optimizations (gcc::context * ctxt)
-+{
-+ return new pass_bbb_optimizations (ctxt);
-+}
-+
-+namespace
-+{
-+
-+ const pass_data pass_data_bbb_baserel =
-+ { RTL_PASS, /* type */
-+ "bebbo's-baserel fixer", /* name */
-+ OPTGROUP_NONE, /* optinfo_flags */
-+ TV_NONE, /* tv_id */
-+ 0, /* properties_required */
-+ 0, /* properties_provided */
-+ 0, /* properties_destroyed */
-+ 0, /* todo_flags_start */
-+ 0, //( TODO_df_finish | TODO_df_verify), /* todo_flags_finish */
-+ };
-+
-+ class pass_bbb_baserel : public rtl_opt_pass
-+ {
-+ public:
-+ pass_bbb_baserel (gcc::context *ctxt) :
-+ rtl_opt_pass (pass_data_bbb_baserel, ctxt), pp (0)
-+ {
-+ }
-+
-+ /* opt_pass methods: */
-+ virtual bool
-+ gate (function *)
-+ {
-+ return TARGET_AMIGA && flag_pic >= 3;
-+ }
-+
-+ virtual unsigned int
-+ execute (function *)
-+ {
-+ return execute_bbb_baserel ();
-+ }
-+
-+ opt_pass *
-+ clone ()
-+ {
-+ pass_bbb_baserel * bbb = new pass_bbb_baserel (m_ctxt);
-+ return bbb;
-+ }
-+
-+ unsigned int pp;
-+
-+ unsigned
-+ execute_bbb_baserel (void);
-+ };
-+// class pass_bbb_optimizations
-+
-+ /* Main entry point to the pass. */
-+ unsigned
-+ pass_bbb_baserel::execute_bbb_baserel (void)
-+ {
-+ rtx_insn *insn, *next;
-+ for (insn = get_insns (); insn; insn = next)
-+ {
-+ next = NEXT_INSN (insn);
-+
-+ if (NONJUMP_INSN_P(insn))
-+ {
-+ rtx set = single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ rtx * src = &SET_SRC(set);
-+ if (MEM_P(*src))
-+ src = &XEXP(*src, 0);
-+
-+ bool ispicref = false;
-+ // fix add PLUS/MINUS into the unspec offset
-+ if (GET_CODE(*src) == PLUS || GET_CODE(*src) == MINUS)
-+ ispicref = amiga_is_const_pic_ref (XEXP(*src, 0));
-+ else
-+ ispicref = amiga_is_const_pic_ref (*src);
-+
-+ if (ispicref)
-+ {
-+ rtx dest = SET_DEST(set);
-+ if (MEM_P(dest) && GET_CODE(XEXP(dest, 0)) != PRE_DEC)
-+ {
-+ // split the insn
-+ rtx reg = gen_reg_rtx (Pmode);
-+
-+ rtx pat0 = gen_rtx_SET(reg, *src);
-+ //rtx_insn * n0 =
-+ emit_insn_before (pat0, insn);
-+
-+ rtx pat1 = gen_rtx_SET(dest, reg);
-+ //rtx_insn * n1 =
-+ emit_insn_before (pat1, insn);
-+
-+ SET_INSN_DELETED(insn);
-+ }
-+ }
-+ }
-+ }
-+
-+ return 0;
-+ }
-+
-+} // anon namespace
-+
-+rtl_opt_pass *
-+make_pass_bbb_baserel (gcc::context * ctxt)
-+{
-+ return new pass_bbb_baserel (ctxt);
-+}
-diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
-index e8bafedd7357..642829b828c7 100644
---- gcc/c/c-decl.c
-+++ gcc/c/c-decl.c
-@@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
- #include "c-family/c-ada-spec.h"
- #include "cilk.h"
- #include "builtins.h"
-+#include "output.h"
-+#include "tm_p.h"
-
- /* In grokdeclarator, distinguish syntactic contexts of declarators. */
- enum decl_context
-@@ -4439,7 +4441,32 @@ c_decl_attributes (tree *node, tree attributes, int flags)
- attributes = tree_cons (get_identifier ("omp declare target"),
- NULL_TREE, attributes);
- }
-- return decl_attributes (node, attributes, flags);
-+
-+ tree returned_attrs = decl_attributes (node, attributes, flags);
-+
-+#ifdef TARGET_AMIGA
-+ /* add an attribute to the function decl's type if there are asm register
parameters. */
-+ if (TREE_CODE (*node) == FUNCTION_DECL)
-+ {
-+ char const * synthetic = "";
-+ for (tree params = TYPE_ARG_TYPES(TREE_TYPE(*node)); params; params =
TREE_CHAIN(params))
-+ {
-+ tree asmattr = lookup_attribute("asm",
TYPE_ATTRIBUTES(TREE_VALUE(params)));
-+ if (asmattr)
-+ synthetic = concat(synthetic,
reg_names[TREE_FIXED_CST_PTR(TREE_VALUE(asmattr))->data.low], NULL);
-+ }
-+ if (strlen(synthetic) > 0)
-+ {
-+ tree asmid = get_identifier("asmregs");
-+ tree syntheticid = get_identifier(synthetic);
-+ tree newattr = tree_cons(asmid, syntheticid, NULL_TREE);
-+
-+ TYPE_ATTRIBUTES(TREE_TYPE(*node)) = chainon(newattr,
TYPE_ATTRIBUTES(TREE_TYPE(*node)));
-+ }
-+ }
-+#endif
-+
-+ return returned_attrs;
- }
-
-
-@@ -5024,6 +5051,29 @@ grokparm (const struct c_parm *parm, tree *expr)
- return decl;
- }
-
-+#ifdef TARGET_AMIGA
-+
-+/* Create a new variant of TYPE, equivalent but distinct.
-+ This is so the caller can modify it. */
-+
-+static tree
-+build_type_copy (tree type)
-+ {
-+ tree t, m = TYPE_MAIN_VARIANT (type);
-+
-+ t = copy_node (type);
-+
-+ TYPE_POINTER_TO (t) = 0;
-+ TYPE_REFERENCE_TO (t) = 0;
-+
-+ /* Add this type to the chain of variants of TYPE. */
-+ TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m);
-+ TYPE_NEXT_VARIANT (m) = t;
-+
-+ return t;
-+ }
-+#endif
-+
- /* Given a parsed parameter declaration, decode it into a PARM_DECL
- and push that on the current scope. EXPR is a pointer to an
- expression that needs to be evaluated for the side effects of array
-@@ -5041,6 +5091,59 @@ push_parm_decl (const struct c_parm *parm, tree *expr)
-
- decl = pushdecl (decl);
-
-+#ifdef TARGET_AMIGAOS
-+ if (parm->asmspec)
-+ {
-+ tree atype = TREE_TYPE(decl);
-+ const char *asmspec = TREE_STRING_POINTER(parm->asmspec);
-+ if (*asmspec == '%')
-+ ++asmspec;
-+ int reg_number = decode_reg_name (asmspec);
-+
-+ /* First detect errors in declaring global registers. */
-+ if (reg_number == -1)
-+ error ("%Jregister name not specified for %qD", decl, decl);
-+ else if (reg_number < 0)
-+ error ("%Jinvalid register name for %qD", decl, decl);
-+ else if (TYPE_MODE (TREE_TYPE (decl)) == BLKmode)
-+ error ("%Jdata type of %qD isn%'t suitable for a register", decl, decl);
-+ else if (!HARD_REGNO_MODE_OK(reg_number, TYPE_MODE (TREE_TYPE (decl))))
-+ error ("%Jregister specified for %qD isn%'t suitable for data type",
-+ decl, decl);
-+ /* Now handle properly declared static register variables. */
-+ else
-+ {
-+ /* Build tree for __attribute__ ((asm(regnum))). */
-+ FIXED_VALUE_TYPE fv =
-+ { reg_number, 0, BImode };
-+ tree ttasm = get_identifier("asm");
-+ tree t, attrs = tree_cons(ttasm, build_fixed (ttasm, fv), NULL_TREE);
-+ /* First check whether such a type already exists - if yes, use
-+ that one. This is very important, since otherwise
-+ common_type() would think that it sees two different
-+ types and would try to merge them - this could result in
-+ warning messages. */
-+ for (t = TYPE_MAIN_VARIANT(atype); t; t = TYPE_NEXT_VARIANT(t))
-+ if (comptypes (t, atype) == 1
-+ && attribute_list_equal (TYPE_ATTRIBUTES(t), attrs))
-+ break;
-+ if (t)
-+ atype = t;
-+ else
-+ {
-+ /* Create a new variant, with differing attributes.
-+ (Hack! Type with differing attributes should no longer be
-+ a variant of its main type. See comment above for
-+ explanation why this was necessary). */
-+ atype = build_type_copy (atype);
-+ TYPE_ATTRIBUTES(atype) = chainon (attrs, TYPE_ATTRIBUTES(atype));
-+ }
-+ TREE_TYPE(decl) = atype;
-+// printf("%s using %s, cdecl=%p, type=%p\n", IDENTIFIER_POINTER(DECL_NAME
(decl)), asmspec, decl, atype);
-+ }
-+ }
-+#endif
-+
- finish_decl (decl, input_location, NULL_TREE, NULL_TREE, NULL_TREE);
- }
-
-diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
-index fc20bad8d992..91cfc2c5e193 100644
---- gcc/c/c-parser.c
-+++ gcc/c/c-parser.c
-@@ -3837,10 +3837,26 @@ c_parser_parameter_declaration (c_parser *parser, tree attrs)
- c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- return NULL;
- }
-+ /**
-+ * SBF: Add support for __asm("xy") register spec.
-+ */
-+#ifdef TARGET_AMIGAOS
-+ tree asmspec = NULL_TREE;
-+ if (c_parser_next_token_is_keyword (parser, RID_ASM))
-+ {
-+ asmspec = c_parser_simple_asm_expr (parser);
-+// printf("asmspec: %s\n", TREE_STRING_POINTER(asmspec));
-+ }
-+#endif
- if (c_parser_next_token_is_keyword (parser, RID_ATTRIBUTE))
- postfix_attrs = c_parser_attributes (parser);
-- return build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
-+
-+ struct c_parm * cparm = build_c_parm (specs, chainon (postfix_attrs, prefix_attrs),
- declarator);
-+#ifdef TARGET_AMIGAOS
-+ cparm->asmspec = asmspec;
-+#endif
-+ return cparm;
- }
-
- /* Parse a string literal in an asm expression. It should not be
-@@ -3892,6 +3908,7 @@ c_parser_asm_string_literal (c_parser *parser)
- static tree
- c_parser_simple_asm_expr (c_parser *parser)
- {
-+ extern int in_assembler_directive;
- tree str;
- gcc_assert (c_parser_next_token_is_keyword (parser, RID_ASM));
- /* ??? Follow the C++ parser rather than using the
-@@ -3903,7 +3920,13 @@ c_parser_simple_asm_expr (c_parser *parser)
- parser->lex_untranslated_string = false;
- return NULL_TREE;
- }
-+
-+ // SBF: set in_assembler_directive to enable multi-line strings. And yes, it's a
HACK.
-+ in_assembler_directive = 1;
- str = c_parser_asm_string_literal (parser);
-+ // SBF: in_assembler_directive disabled
-+ in_assembler_directive = 0;
-+
- parser->lex_untranslated_string = false;
- if (!c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>"))
- {
-diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
-index bb12a200f709..e3404fd8b0a6 100644
---- gcc/c/c-tree.h
-+++ gcc/c/c-tree.h
-@@ -453,6 +453,10 @@ struct c_parm {
- tree attrs;
- /* The declarator. */
- struct c_declarator *declarator;
-+#ifdef TARGET_AMIGAOS
-+ /* The optional asm spec to specify the register. */
-+ tree asmspec;
-+#endif
- };
-
- /* Used when parsing an enum. Initialized by start_enum. */
-diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
-index 6e92d4cdde22..378b1fc595bb 100644
---- gcc/cfgcleanup.c
-+++ gcc/cfgcleanup.c
-@@ -2001,6 +2001,15 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- {
- rtx_insn *insn;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * we need replicated labels, if the labels are too far away,
-+ * since on 68000 there are only 8 bits for the offset.
-+ */
-+ if (!TARGET_68020 && !TARGET_68040)
-+ return false;
-+#endif
-+
- /* Replace references to LABEL1 with LABEL2. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- {
-@@ -2016,8 +2025,9 @@ try_crossjump_to_edge (int mode, edge e1, edge e2,
- /* Avoid splitting if possible. We must always split when SRC2 has
- EH predecessor edges, or we may end up with basic blocks with both
- normal and EH predecessor edges. */
-- if (newpos2 == BB_HEAD (src2)
-+ if ((newpos2 == BB_HEAD (src2)
- && !(EDGE_PRED (src2, 0)->flags & EDGE_EH))
-+ )
- redirect_to = src2;
- else
- {
-diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
-index b612293b1a7a..4215ae90c63d 100644
---- gcc/cfgexpand.c
-+++ gcc/cfgexpand.c
-@@ -2732,6 +2732,10 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET
*clobbered_regs)
- {
- /* Conflicts between asm-declared register variables and the clobber
- list are not allowed. */
-+ /*
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- tree overlap = tree_overlaps_hard_reg_set (t, clobbered_regs);
-
- if (overlap)
-@@ -2744,7 +2748,7 @@ tree_conflicts_with_clobbers_p (tree t, HARD_REG_SET
*clobbered_regs)
- DECL_REGISTER (overlap) = 0;
- return true;
- }
--
-+#endif
- return false;
- }
-
-@@ -3255,11 +3259,15 @@ expand_asm_stmt (gasm *stmt)
- if (reg_overlap_mentioned_p (clobbered_reg, output_rvec[k]))
- internal_error ("asm clobber conflict with output operand");
-
-+/**
-+ * SBF: Why?
-+ */
-+#ifndef TARGET_AMIGA
- for (unsigned k = 0; k < ninputs - ninout; ++k)
- if (reg_overlap_mentioned_p (clobbered_reg, input_rvec[k]))
- internal_error ("asm clobber conflict with input operand");
-+#endif
- }
--
- XVECEXP (body, 0, i++) = gen_rtx_CLOBBER (VOIDmode, clobbered_reg);
- }
-
-diff --git a/gcc/collect2.c b/gcc/collect2.c
-index bffac802b8fe..f52a66ef1b58 100644
---- gcc/collect2.c
-+++ gcc/collect2.c
-@@ -1392,6 +1392,11 @@ main (int argc, char **argv)
- add_to_list (&libs, s);
- }
- #endif
-+ /* begin-GG-local: dynamic libraries */
-+ #ifdef COLLECT2_LIBNAME_HOOK
-+ COLLECT2_LIBNAME_HOOK(arg);
-+ #endif
-+ /* end-GG-local */
- break;
-
- #ifdef COLLECT_EXPORT_LIST
-@@ -1492,6 +1497,11 @@ main (int argc, char **argv)
- add_to_list (&libs, arg);
- }
- #endif
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_LIBNAME_HOOK
-+ COLLECT2_LIBNAME_HOOK(arg);
-+#endif
-+ /* end-GG-local */
- }
- }
-
-@@ -1608,6 +1618,11 @@ main (int argc, char **argv)
-
- fprintf (stderr, "\n");
- }
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_PRELINK_HOOK
-+ COLLECT2_PRELINK_HOOK(ld1_argv, &strip_flag);
-+#endif
-+ /* end-GG-local */
-
- /* Load the program, searching all libraries and attempting to provide
- undefined symbols from repository information.
-@@ -1648,6 +1663,8 @@ main (int argc, char **argv)
- }
- }
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifndef COLLECT2_POSTLINK_HOOK
- /* Unless we have done it all already, examine the namelist and search for
- static constructors and destructors to call. Write the constructor and
- destructor tables to a .s file and reload. */
-@@ -1674,6 +1691,10 @@ main (int argc, char **argv)
- frame_tables.number),
- frame_tables.number);
- }
-+#else /* COLLECT2_POSTLINK_HOOK */
-+ COLLECT2_POSTLINK_HOOK(output_file);
-+#endif
-+/* end-GG-local */
-
- /* If the scan exposed nothing of special interest, there's no need to
- generate the glue code and relink so return now. */
-@@ -1716,6 +1737,11 @@ main (int argc, char **argv)
-
- maybe_unlink (c_file);
- maybe_unlink (o_file);
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_EXTRA_CLEANUP
-+ COLLECT2_EXTRA_CLEANUP();
-+#endif
-+ /* end-GG-local */
- return 0;
- }
-
-@@ -1821,6 +1847,11 @@ main (int argc, char **argv)
- maybe_unlink (export_file);
- #endif
-
-+ /* begin-GG-local: dynamic libraries */
-+#ifdef COLLECT2_EXTRA_CLEANUP
-+ COLLECT2_EXTRA_CLEANUP();
-+#endif
-+ /* end-GG-local */
- return 0;
- }
-
-diff --git a/gcc/config.gcc b/gcc/config.gcc
-index bf3f32da08ac..7aa190620911 100644
---- gcc/config.gcc
-+++ gcc/config.gcc
-@@ -1940,6 +1940,27 @@ m68k-*-elf* | fido-*-elf*)
- ;;
- esac
- ;;
-+m68k*-*-amigaosvasm*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_AMIGAOS_VASM
TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ ;;
-+m68k*-*-amigaos*)
-+ default_m68k_cpu=68000
-+ tm_file="${tm_file} dbx.h newlib-stdint.h m68k/m68kamigaos.h"
-+ tm_defines="${tm_defines} MOTOROLA=1 TARGET_AMIGAOS TARGET_CPU_DEFAULT=0"
-+ tmake_file="m68k/t-floatlib m68k/t-m68kbare m68k/t-amigaos"
-+ tm_p_file="${tm_p_file} m68k/amigaos-protos.h"
-+ extra_objs=amigaos.o
-+ extra_options="${extra_options} m68k/amigaos.opt"
-+ gnu_ld=yes
-+ CFLAGS="-Os"
-+ ;;
- m68k*-*-netbsdelf*)
- default_m68k_cpu=68020
- default_cf_cpu=5475
-diff --git a/gcc/config/m68k/amigaos-protos.h b/gcc/config/m68k/amigaos-protos.h
-new file mode 100644
-index 000000000000..e5cd6e950b52
---- /dev/null
-+++ gcc/config/m68k/amigaos-protos.h
-@@ -0,0 +1,55 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#undef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *, tree, tree);
-+
-+/* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+#undef INIT_CUMULATIVE_ARGS
-+#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, INDIRECT, N_NAMED_ARGS) \
-+ (amigaos_init_cumulative_args(&(CUM), (FNTYPE), (INDIRECT)))
-+
-+#ifdef RTX_CODE
-+extern int read_only_operand (rtx);
-+extern void amigaos_select_section (tree, int, unsigned HOST_WIDE_INT);
-+extern void amigaos_encode_section_info (tree, rtx, int);
-+extern void amigaos_alternate_pic_setup (FILE *);
-+extern void amigaos_prologue_begin_hook (FILE *, int);
-+extern void amigaos_alternate_frame_setup_f (FILE *, int);
-+extern void amigaos_alternate_frame_setup (FILE *, int);
-+extern struct rtx_def* gen_stack_cleanup_call (rtx, rtx);
-+extern void amigaos_alternate_allocate_stack (rtx *);
-+#ifdef TREE_CODE
-+//extern void amigaos_function_arg_advance (CUMULATIVE_ARGS *);
-+extern struct rtx_def *amigaos_function_arg (CUMULATIVE_ARGS *, enum machine_mode,
tree);
-+#endif
-+#endif
-+#ifdef TREE_CODE
-+extern tree amigaos_handle_decl_attribute (tree *, tree, tree, int, bool *);
-+extern tree amigaos_handle_type_attribute (tree *, tree, tree, int, bool *);
-+#endif
-diff --git a/gcc/config/m68k/amigaos.c b/gcc/config/m68k/amigaos.c
-new file mode 100644
-index 000000000000..28d20a980978
---- /dev/null
-+++ gcc/config/m68k/amigaos.c
-@@ -0,0 +1,931 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+ This file is part of GCC.
-+
-+ GCC is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; either version 2, or (at your option)
-+ any later version.
-+
-+ GCC is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with GCC; see the file COPYING. If not, write to
-+ the Free Software Foundation, 59 Temple Place - Suite 330,
-+ Boston, MA 02111-1307, USA. */
-+
-+//work without flag_writable_strings which is not in GCC4
-+#define REGPARMS_68K 1
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "rtl.h"
-+#include "output.h"
-+#include "tree.h"
-+#include "attribs.h"
-+#include "flags.h"
-+#include "expr.h"
-+#include "toplev.h"
-+#include "tm_p.h"
-+#include "target.h"
-+#include "diagnostic-core.h"
-+#include "langhooks.h"
-+#include "function.h"
-+#include "config/m68k/amigaos.h"
-+
-+//#define MYDEBUG 1
-+#ifdef MYDEBUG
-+#define DPRINTF(x) printf x; fflush(stdout);
-+#else
-+#define DPRINTF(x)
-+#endif
-+
-+//int amiga_declare_object;
-+
-+#if 0
-+
-+//----- from 68k.c start
-+
-+/* Stack checking and automatic extension support. */
-+
-+void
-+amigaos_prologue_begin_hook (FILE *stream, int fsize)
-+ {
-+ if (TARGET_STACKCHECK)
-+ {
-+ if (fsize < 256)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tjra %U__stkovf\n"
-+ "\t0:\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")));
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__stkchk_d0\n",
-+ fsize);
-+ }
-+ }
-+
-+
-+//static rtx
-+//gen_stack_management_call (rtx stack_pointer, rtx arg, const char *func)
-+//{
-+// rtx call_insn, call, seq, name;
-+// start_sequence ();
-+//
-+// /* Move arg to d0. */
-+// emit_move_insn (gen_rtx_REG (SImode, 0), arg);
-+//
-+// /* Generate the function reference. */
-+// name = gen_rtx_SYMBOL_REF (Pmode, func);
-+// SYMBOL_REF_FLAG (name) = 1;
-+// /* If optimizing, put it in a psedo so that several loads can be merged
-+// into one. */
-+// if (optimize && ! flag_no_function_cse)
-+// name = copy_to_reg (name);
-+//
-+// /* Generate the function call. */
-+// call = gen_rtx_CALL (VOIDmode, gen_rtx_MEM (FUNCTION_MODE, name),
-+// const0_rtx);
-+// /* If we are doing stack extension, notify about the sp change. */
-+// if (stack_pointer)
-+// call = gen_rtx_SET (VOIDmode, stack_pointer, call);
-+//
-+// /* Generate the call instruction. */
-+// call_insn = emit_call_insn (call);
-+// /* Stack extension does not change memory in an unpredictable way. */
-+// RTL_CONST_OR_PURE_CALL_P (call_insn) = 1;
-+// /* We pass an argument in d0. */
-+// CALL_INSN_FUNCTION_USAGE (call_insn) = gen_rtx_EXPR_LIST (VOIDmode,
-+// gen_rtx_USE (VOIDmode, gen_rtx_REG (SImode, 0)), 0);
-+//
-+// seq = get_insns ();
-+// end_sequence ();
-+// return seq;
-+//}
-+//
-+//rtx
-+//gen_stack_cleanup_call (rtx stack_pointer, rtx sa)
-+//{
-+// return gen_stack_management_call (stack_pointer, sa, "__move_d0_sp");
-+//}
-+//
-+//void
-+//amigaos_alternate_allocate_stack (rtx *operands)
-+//{
-+// if (TARGET_STACKEXTEND)
-+// emit_insn (gen_stack_management_call (stack_pointer_rtx, operands[1],
-+// "__sub_d0_sp"));
-+// else
-+// {
-+// if (TARGET_STACKCHECK)
-+// emit_insn (gen_stack_management_call (0, operands[1], "__stkchk_d0"));
-+// anti_adjust_stack (operands[1]);
-+// }
-+// emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
-+//}
-+#endif
-+
-+/*
-+ * begin-GG-local: explicit register specification for parameters.
-+ *
-+ * Reworked and ported to gcc-6.2.0 by Stefan "Bebbo" Franke.
-+ */
-+
-+/**
-+ * Define this here and add it to tm_p -> all know the custom type and allocate/use
the correct size.
-+ */
-+struct amigaos_args
-+{
-+ int num_of_regs;
-+ long regs_already_used;
-+ int last_arg_reg;
-+ int last_arg_len;
-+ tree formal_type; /* New field: formal type of the current argument. */
-+};
-+
-+static struct amigaos_args mycum, othercum;
-+
-+/* Argument-passing support functions. */
-+
-+/* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+void
-+amigaos_init_cumulative_args (CUMULATIVE_ARGS *cump, tree fntype, tree decl)
-+{
-+ struct amigaos_args * cum = decl == current_function_decl ? &mycum :
&othercum;
-+ *cump = decl == current_function_decl;
-+ cum->num_of_regs = amigaos_regparm > 0 ? amigaos_regparm : 0;
-+ DPRINTF(
-+ ("0amigaos_init_cumulative_args %s %p -> %d\r\n", decl ?
lang_hooks.decl_printable_name (decl, 2) : "?", cum, cum->num_of_regs));
-+
-+ /* Initialize a variable CUM of type CUMULATIVE_ARGS
-+ for a call to a function whose data type is FNTYPE.
-+ For a library call, FNTYPE is 0. */
-+
-+ cum->last_arg_reg = -1;
-+ cum->regs_already_used = 0;
-+
-+ if (fntype)
-+ {
-+ tree attrs = TYPE_ATTRIBUTES(fntype);
-+ if (attrs)
-+ {
-+ if (lookup_attribute ("stkparm", attrs))
-+ cum->num_of_regs = 0;
-+ else
-+ {
-+ tree ratree = lookup_attribute ("regparm", attrs);
-+ cum->num_of_regs = amigaos_regparm != 0 ?
-+ amigaos_regparm :
-+ AMIGAOS_DEFAULT_REGPARM;
-+ if (ratree)
-+ {
-+ tree args = TREE_VALUE(ratree);
-+
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no > 0 && no < AMIGAOS_MAX_REGPARM)
-+ cum->num_of_regs = no;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ }
-+ else
-+ /* Libcall. */
-+ cum->num_of_regs = 0;
-+
-+ if (cum->num_of_regs)
-+ {
-+ /* If this is a vararg call, put all arguments on stack. */
-+ tree param, next_param;
-+ for (param = TYPE_ARG_TYPES(fntype); param; param = next_param)
-+ {
-+ next_param = TREE_CHAIN(param);
-+ if (!next_param && TREE_VALUE (param) != void_type_node)
-+ cum->num_of_regs = 0;
-+ }
-+ }
-+
-+#if ! defined (PCC_STATIC_STRUCT_RETURN) && defined (M68K_STRUCT_VALUE_REGNUM)
-+ /* If return value is a structure, and we pass the buffer address in a
-+ register, we can't use this register for our own purposes.
-+ FIXME: Something similar would be useful for static chain. */
-+ if (fntype && aggregate_value_p (TREE_TYPE(fntype), fntype))
-+ cum->regs_already_used |= (1 << M68K_STRUCT_VALUE_REGNUM);
-+#endif
-+
-+ if (fntype && DECL_STATIC_CHAIN(fntype))
-+ {
-+ rtx reg = amigaos_static_chain_rtx (decl, 0);
-+ if (reg)
-+ cum->regs_already_used |= (1 << REGNO(reg));
-+ }
-+
-+ if (fntype)
-+ cum->formal_type = TYPE_ARG_TYPES(fntype);
-+ else
-+ /* Call to compiler-support function. */
-+ cum->formal_type = 0;
-+ DPRINTF(("1amigaos_init_cumulative_args %p -> %d\r\n", cum,
cum->num_of_regs));
-+}
-+
-+int
-+amigaos_function_arg_reg (unsigned regno)
-+{
-+ return (mycum.regs_already_used & (1 << regno)) != 0;
-+}
-+
-+/* Update the data in CUM to advance over an argument. */
-+
-+void
-+amigaos_function_arg_advance (cumulative_args_t cum_v, machine_mode, const_tree, bool)
-+{
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-+ /* Update the data in CUM to advance over an argument. */
-+
-+ DPRINTF(("amigaos_function_arg_advance1 %p\r\n", cum));
-+
-+ if (cum->last_arg_reg != -1)
-+ {
-+ int count;
-+ for (count = 0; count < cum->last_arg_len; count++)
-+ cum->regs_already_used |= (1 << (cum->last_arg_reg + count));
-+ cum->last_arg_reg = -1;
-+ }
-+
-+ if (cum->formal_type)
-+ cum->formal_type = TREE_CHAIN(cum->formal_type);
-+}
-+
-+/* Define where to put the arguments to a function.
-+ Value is zero to push the argument on the stack,
-+ or a hard register in which to store the argument.
-+
-+ MODE is the argument's machine mode.
-+ TYPE is the data type of the argument (as a tree).
-+ This is null for libcalls where that information may
-+ not be available.
-+ CUM is a variable of type CUMULATIVE_ARGS which gives info about
-+ the preceding args and about the function being called. */
-+
-+static struct rtx_def *
-+_m68k_function_arg (struct amigaos_args * cum, machine_mode mode, const_tree type)
-+{
-+ DPRINTF(("m68k_function_arg numOfRegs=%d\r\n", cum ? cum->num_of_regs :
0));
-+
-+ if (cum->num_of_regs)
-+ {
-+ int regbegin = -1, altregbegin = -1, len;
-+
-+ /* FIXME: The last condition below is a workaround for a bug. */
-+ if (TARGET_68881 && FLOAT_MODE_P(mode) &&
-+ GET_MODE_UNIT_SIZE (mode) <= 12 && (GET_MODE_CLASS (mode) !=
MODE_COMPLEX_FLOAT || mode == SCmode))
-+ {
-+ regbegin = 16; /* FPx */
-+ len = GET_MODE_NUNITS(mode);
-+ }
-+ /* FIXME: Two last conditions below are workarounds for bugs. */
-+ else if (INTEGRAL_MODE_P (mode) && mode != CQImode && mode !=
CHImode)
-+ {
-+ if (!type || POINTER_TYPE_P(type))
-+ regbegin = 8; /* Ax */
-+ else
-+ regbegin = 0; /* Dx */
-+ altregbegin = 8 - regbegin;
-+ len = (GET_MODE_SIZE (mode) + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
-+ }
-+
-+ if (regbegin != -1)
-+ {
-+ int reg;
-+ long mask;
-+
-+ look_for_reg: mask = 1 << regbegin;
-+ for (reg = 0; reg < cum->num_of_regs; reg++, mask <<= 1)
-+ if (!(cum->regs_already_used & mask))
-+ {
-+ int end;
-+ for (end = reg; end < cum->num_of_regs && end < reg + len; end++,
mask <<= 1)
-+ if (cum->regs_already_used & mask)
-+ break;
-+ if (end == reg + len)
-+ {
-+ cum->last_arg_reg = reg + regbegin;
-+ cum->last_arg_len = len;
-+ break;
-+ }
-+ }
-+
-+ if (reg == cum->num_of_regs && altregbegin != -1)
-+ {
-+ DPRINTF(("look for alt reg\n"));
-+ regbegin = altregbegin;
-+ altregbegin = -1;
-+ goto look_for_reg;
-+ }
-+ }
-+
-+ if (cum->last_arg_reg != -1)
-+ {
-+ DPRINTF(("-> gen_rtx_REG %d\r\n", cum->last_arg_reg));
-+ return gen_rtx_REG (mode, cum->last_arg_reg);
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* A C expression that controls whether a function argument is passed
-+ in a register, and which register. */
-+
-+struct rtx_def *
-+amigaos_function_arg (cumulative_args_t cum_v, machine_mode mode, const_tree type,
bool)
-+{
-+ DPRINTF(("amigaos_function_arg %p\r\n", cum_v.p));
-+
-+ struct amigaos_args *cum = *get_cumulative_args (cum_v) ? &mycum : &othercum;
-+
-+ tree asmtree = type ? TYPE_ATTRIBUTES(cum->formal_type ?
TREE_VALUE(cum->formal_type) : type) : NULL_TREE;
-+ //tree asmtree = type ? TYPE_ATTRIBUTES(type) : NULL_TREE;
-+
-+ if (asmtree && 0 == strcmp ("asm",
IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ {
-+ int i;
-+ cum->last_arg_reg = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ cum->last_arg_len = HARD_REGNO_NREGS(cum->last_arg_reg, mode);
-+
-+ for (i = 0; i < cum->last_arg_len; i++)
-+ {
-+ if (cum->regs_already_used & (1 << (cum->last_arg_reg + i)))
-+ {
-+ error ("two parameters allocated for one register");
-+ break;
-+ }
-+ cum->regs_already_used |= (1 << (cum->last_arg_reg + i));
-+ }
-+ return gen_rtx_REG (mode, cum->last_arg_reg);
-+ }
-+ return _m68k_function_arg (cum, mode, type);
-+}
-+
-+void
-+amiga_emit_regparm_clobbers (void)
-+{
-+ for (int i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
-+ if (mycum.regs_already_used & (1 << i))
-+ {
-+ rtx reg = gen_raw_REG (Pmode, i);
-+ emit_insn (gen_rtx_CLOBBER(Pmode, gen_rtx_SET(reg, gen_rtx_MEM(Pmode, reg))));
-+ }
-+}
-+
-+/* Return zero if the attributes on TYPE1 and TYPE2 are incompatible,
-+ one if they are compatible, and two if they are nearly compatible
-+ (which causes a warning to be generated). */
-+
-+int
-+amigaos_comp_type_attributes (const_tree type1, const_tree type2)
-+{
-+ DPRINTF(("amigaos_comp_type_attributes\n"));
-+ /* Functions or methods are incompatible if they specify mutually exclusive
-+ ways of passing arguments. */
-+ if (TREE_CODE(type1) == FUNCTION_TYPE || TREE_CODE(type1) == METHOD_TYPE)
-+ {
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree asm1 = lookup_attribute("asmregs", attrs1);
-+ tree stack1 = lookup_attribute("stkparm", attrs1);
-+ tree reg1 = lookup_attribute("regparm", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree asm2 = lookup_attribute("asmregs", attrs2);
-+ tree stack2 = lookup_attribute("stkparm", attrs2);
-+ tree reg2 = lookup_attribute("regparm", attrs2);
-+
-+ if (reg1)
-+ {
-+ if (stack2 || asm2)
-+ return 0;
-+
-+ int no1 = TREE_INT_CST_LOW(TREE_VALUE(reg1));
-+ int no2 = reg2 ? TREE_INT_CST_LOW(TREE_VALUE(reg2)) : amigaos_regparm;
-+ return no1 == no2;
-+ }
-+
-+ if (reg2)
-+ {
-+ if (stack1 || asm1)
-+ return 0;
-+
-+ int no2 = TREE_INT_CST_LOW(TREE_VALUE(reg2));
-+ return amigaos_regparm == no2;
-+ }
-+
-+ if (stack1) {
-+ if (stack2)
-+ return 1;
-+ return amigaos_regparm == 0;
-+ }
-+
-+ if (stack2)
-+ return amigaos_regparm == 0;
-+
-+ if (asm1)
-+ {
-+ if (!asm2)
-+ return 0;
-+
-+ return 0 == strcmp(IDENTIFIER_POINTER(TREE_VALUE(asm1)),
IDENTIFIER_POINTER(TREE_VALUE(asm2)));
-+ }
-+
-+ if (asm2)
-+ return 0;
-+
-+ }
-+ else
-+ {
-+ tree attrs1 = TYPE_ATTRIBUTES(type1);
-+
-+ tree chip1 = lookup_attribute("chip", attrs1);
-+ tree fast1 = lookup_attribute("fast", attrs1);
-+ tree far1 = lookup_attribute("far", attrs1);
-+
-+ tree attrs2 = TYPE_ATTRIBUTES(type2);
-+
-+ tree chip2 = lookup_attribute("chip", attrs2);
-+ tree fast2 = lookup_attribute("fast", attrs2);
-+ tree far2 = lookup_attribute("far", attrs2);
-+
-+ if (chip1)
-+ return chip2 && !fast2 && !far2;
-+
-+ if (fast1)
-+ return !chip2 && fast2 && !far2;
-+
-+ if (far1)
-+ return !chip2 && !fast2 && far2;
-+
-+ return !chip2 && !fast2 && !far2;
-+ }
-+ return 1;
-+}
-+/* end-GG-local */
-+
-+/* Handle a regparm, stkparm, saveds attribute;
-+ arguments as in struct attribute_spec.handler. */
-+tree
-+amigaos_handle_type_attribute (tree *node, tree name, tree args, int flags
ATTRIBUTE_UNUSED, bool *no_add_attrs)
-+{
-+ tree nnn = *node;
-+ do
-+ { // while (0);
-+ DPRINTF(("%p with treecode %d\n", node, TREE_CODE(nnn)));
-+ if (TREE_CODE (nnn) == FUNCTION_DECL || TREE_CODE (nnn) == FUNCTION_TYPE ||
TREE_CODE (nnn) == METHOD_TYPE)
-+ {
-+ /* 'regparm' accepts one optional argument - number of registers in
-+ single class that should be used to pass arguments. */
-+ if (is_attribute_p ("regparm", name))
-+ {
-+ DPRINTF(("regparm found\n"));
-+
-+ if (lookup_attribute ("stkparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ if (args && TREE_CODE (args) == TREE_LIST)
-+ {
-+ tree val = TREE_VALUE(args);
-+ DPRINTF(("regparm with val: %d\n", TREE_CODE(val)));
-+ if (TREE_CODE (val) == INTEGER_CST)
-+ {
-+ int no = TREE_INT_CST_LOW(val);
-+ if (no < 0 || no > AMIGAOS_MAX_REGPARM)
-+ {
-+ error ("`regparm' attribute: value %d not in [0 - %d]", no,
-+ AMIGAOS_MAX_REGPARM);
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ error ("invalid argument(s) to `regparm' attribute");
-+ break;
-+ }
-+ }
-+ }
-+ else if (is_attribute_p ("stkparm", name))
-+ {
-+ if (lookup_attribute ("regparm", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`regparm' and `stkparm' are mutually exclusive");
-+ break;
-+ }
-+ }
-+ else if (is_attribute_p ("stackext", name))
-+ {
-+ if (lookup_attribute ("interrupt", TYPE_ATTRIBUTES(nnn)))
-+ {
-+ error ("`stackext' and `interrupt' are mutually exclusive");
-+ break;
-+ }
-+ }
-+ else if (is_attribute_p ("saveds", name))
-+ {
-+ if (flag_pic < 3)
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute is only usable with
fbaserel", IDENTIFIER_POINTER(name));
-+ }
-+ else
-+ if (flag_resident)
-+ {
-+ error ("`saveds' can't be used with resident!\n");
-+ }
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to data",
IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ else
-+ {
-+ if (is_attribute_p ("chip", name) || is_attribute_p ("fast",
name) || is_attribute_p ("far", name))
-+ {
-+ // OK
-+ }
-+ else
-+ {
-+ warning (OPT_Wattributes, "`%s' attribute only applies to
functions", IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ return NULL_TREE ;
-+ }
-+ while (0);
-+ // error case
-+ *no_add_attrs = true;
-+ return NULL_TREE ;
-+}
-+
-+#define AMIGA_CHIP_SECTION_NAME ".datachip"
-+#define AMIGA_FAST_SECTION_NAME ".datafast"
-+#define AMIGA_FAR_SECTION_NAME ".datafar"
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr)
-+{
-+ if (!*attr)
-+ return;
-+
-+ tree name = TREE_PURPOSE(*attr);
-+
-+ if (is_attribute_p("chip", name) || is_attribute_p("far", name) ||
is_attribute_p("fast", name))
-+ {
-+ if (!TREE_TYPE(decl) == VAR_DECL)
-+ {
-+ error ("`%s' attribute can only be specified for variables",
IDENTIFIER_POINTER(name));
-+ return;
-+ }
-+
-+ if (! TREE_STATIC (decl) && ! DECL_EXTERNAL (decl))
-+ {
-+ error ("`%s' attribute cannot be specified for local variables",
IDENTIFIER_POINTER(name));
-+ return;
-+ }
-+
-+ char const * section_name;
-+ if (is_attribute_p("chip", name))
-+ section_name = AMIGA_CHIP_SECTION_NAME;
-+ else if (is_attribute_p("fast", name))
-+ section_name = AMIGA_FAST_SECTION_NAME;
-+ else if (is_attribute_p("far", name))
-+ section_name = AMIGA_FAR_SECTION_NAME;
-+
-+
-+ /* The decl may have already been given a section attribute from
-+ a previous declaration. Ensure they match. */
-+ if (DECL_SECTION_NAME (decl) == NULL)
-+ set_decl_section_name(decl, section_name);
-+ else if (strcmp (DECL_SECTION_NAME (decl), section_name) )
-+ {
-+ error_at (DECL_SOURCE_LOCATION(decl),
-+ "`%s' attribute conflicts with previous declaration",
IDENTIFIER_POINTER(name));
-+ }
-+ }
-+ else
-+ {
-+// warning (OPT_Wattributes, "`%s' attribute unknown",
IDENTIFIER_POINTER(name));
-+ }
-+}
-+
-+extern bool
-+m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+
-+bool
-+amigaos_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno, int *total, bool
speed)
-+{
-+// DPRINTF(("outer: %d, opno: %d", outer_code, opno));
-+ bool r = m68k_rtx_costs (x, mode, outer_code, opno, total, speed);
-+// *total *= 4;
-+// fprintf(stderr, "costs: %d, mode=%d, outer=%d, opno=%d, speed=%d,
ok=%d\n", *total * 4, mode, outer_code, opno, speed, r);
-+// debug_rtx(x);
-+ return r;
-+}
-+
-+/* Output assembly to switch to section NAME with attribute FLAGS. */
-+#ifndef TARGET_AMIGAOS_VASM
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl )
-+{
-+ // only one code section - TODO: with amiga hunk this is no longer mandatory.
-+ if (0 == strncmp (".text", name, 5))
-+ name = ".text";
-+
-+ if (0 == strncmp(".data", name, 5) && (!DECL_INITIAL (decl) ||
initializer_zerop (DECL_INITIAL (decl))))
-+ fprintf (asm_out_file, "\t.bss%s\n", name + 5);
-+ else
-+ fprintf (asm_out_file, "\t%s\n", name);
-+}
-+#else
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl ATTRIBUTE_UNUSED)
-+ {
-+ if (0 == strncmp(".text", name, 5))
-+ name = ".text";
-+
-+ if (0 == strncmp("section ", name, 8))
-+ {
-+// fprintf (asm_out_file, "\t.section\t%s\n", name);
-+ fprintf (asm_out_file, "\t%s\n", name);
-+ }
-+ else
-+ {
-+ fprintf (asm_out_file, "\tsection %s\n", name);
-+ }
-+ }
-+#endif
-+
-+/* Baserel support. */
-+
-+/**
-+ * Does x reference the pic_reg and is const or plus?
-+ */
-+static int
-+_amiga_is_const_pic_ref (const_rtx x)
-+{
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS)
-+ {
-+ if (GET_CODE(XEXP(x, 1)) == CONST_INT)
-+ return _amiga_is_const_pic_ref(XEXP(x, 0));
-+ return false;
-+ }
-+
-+ if (GET_CODE(x) == CONST)
-+ x = XEXP(x, 0);
-+ if (GET_CODE(x) != PLUS)
-+ return false;
-+
-+ const_rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg) && REGNO(reg) != PIC_REG)
-+ return false;
-+
-+ const_rtx unspec = XEXP(x, 1);
-+ while (GET_CODE(unspec) == PLUS || GET_CODE(unspec) == CONST)
-+ unspec = XEXP(unspec, 0);
-+
-+ if (GET_CODE(unspec) != UNSPEC)
-+ return false;
-+
-+ return true;
-+}
-+
-+int
-+amiga_is_const_pic_ref (const_rtx cnst)
-+{
-+ if (flag_pic < 3)
-+ return false;
-+ int r = _amiga_is_const_pic_ref (cnst);
-+// fprintf(stderr, r ? "valid pic: " : "invalid pic: ");
-+// debug_rtx(cnst);
-+ return r;
-+}
-+
-+
-+/* Does operand (which is a symbolic_operand) live in text space? If
-+ so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true.
-+
-+ This function is used in base relative code generation. */
-+
-+int
-+read_only_operand (rtx operand)
-+{
-+ if (GET_CODE (operand) == CONST)
-+ operand = XEXP(XEXP (operand, 0), 0);
-+ if (GET_CODE (operand) == SYMBOL_REF)
-+ return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P(operand);
-+ return 1;
-+}
-+
-+rtx
-+amigaos_struct_value_rtx (tree fntype, int incoming ATTRIBUTE_UNUSED)
-+{
-+ return gen_rtx_REG (Pmode, M68K_STRUCT_VALUE_REGNUM);
-+}
-+
-+rtx
-+amigaos_static_chain_rtx (const_tree decl, bool incoming ATTRIBUTE_UNUSED)
-+{
-+ if (!decl || !DECL_STATIC_CHAIN(decl))
-+ return 0;
-+
-+ unsigned used = 0;
-+ tree fntype = TREE_TYPE(decl);
-+ if (fntype)
-+ for (tree formal_type = TYPE_ARG_TYPES(fntype); formal_type; formal_type =
TREE_CHAIN(formal_type))
-+ {
-+ tree asmtree = TYPE_ATTRIBUTES(TREE_VALUE(formal_type));
-+ if (!asmtree || strcmp ("asm", IDENTIFIER_POINTER(TREE_PURPOSE(asmtree))))
-+ continue;
-+
-+ unsigned regno = TREE_FIXED_CST_PTR(TREE_VALUE(asmtree))->data.low;
-+ used |= 1 << regno;
-+ }
-+
-+ if (!(used & (1 << 9)))
-+ return gen_rtx_REG (Pmode, 9);
-+ if (!(used & (1 << 10)))
-+ return gen_rtx_REG (Pmode, 10);
-+ if (!(used & (1 << 11)))
-+ return gen_rtx_REG (Pmode, 11);
-+ if (!(used & (1 << 14)))
-+ return gen_rtx_REG (Pmode, 14);
-+
-+ return 0;
-+}
-+
-+/**
-+ * Necessary to block some funny invalid combinations if baserel is used:
-+ *
-+(const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+
-+(plus:SI (reg:SI 10 a2)
-+ (const:SI (minus:SI (neg:SI (reg:SI 12 a4))
-+ (const:SI (plus:SI (unspec:SI [
-+ (symbol_ref:SI ("xyz") <var_decl 0xffcf0000 xyz>)
-+ (const_int 0 [0])
-+ ] 6)
-+ (const_int 1234 [0xe00]))))))) xyz.c:41 465 {*lea}
-+
-+ */
-+bool
-+amigaos_legitimate_src (rtx src)
-+{
-+ if (flag_pic < 3)
-+ return true;
-+
-+ if (MEM_P(src))
-+ {
-+ rtx x = XEXP(src, 0);
-+ if (GET_CODE(x) == PLUS || GET_CODE(x) == MINUS) {
-+ if (amiga_is_const_pic_ref(XEXP(x, 0))
-+ || amiga_is_const_pic_ref(XEXP(x, 1)))
-+ return false;
-+ }
-+ return true;
-+ }
-+
-+ if (GET_CODE(src) == PLUS || GET_CODE(src) == MINUS)
-+ {
-+ rtx x = XEXP(src, 0);
-+ rtx y = XEXP(src, 1);
-+
-+ /** handled in print_operand_address(...) */
-+ if (amiga_is_const_pic_ref(x))
-+ return GET_CODE(y) == CONST_INT;
-+
-+ return amigaos_legitimate_src(x) && amigaos_legitimate_src(y) &&
!amiga_is_const_pic_ref(y);
-+ }
-+
-+ if (GET_CODE(src) == CONST)
-+ {
-+ rtx op = XEXP(src, 0);
-+ if (GET_CODE(op) == MINUS || GET_CODE(op) == PLUS)
-+ {
-+ rtx x = XEXP(op, 0);
-+ if (GET_CODE(x) == NOT || GET_CODE(x) == NEG || GET_CODE(x) == SIGN_EXTEND)
-+ {
-+ rtx reg = XEXP(x, 0);
-+ if (!REG_P(reg))
-+ return true;
-+
-+ return false;
-+ }
-+ }
-+
-+ if (GET_CODE(op) == UNSPEC)
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+void
-+amigaos_restore_a4 (void)
-+ {
-+ if (flag_pic >= 3 && !flag_resident)
-+ {
-+ tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl));
-+ tree attr = lookup_attribute ("saveds", attrs);
-+ if (attr || TARGET_RESTORE_A4 || TARGET_ALWAYS_RESTORE_A4)
-+ {
-+ rtx a4 = gen_rtx_ASM_INPUT_loc(VOIDmode, "\tlea ___a4_init,a4",
DECL_SOURCE_LOCATION (current_function_decl));
-+ a4->volatil = 1;
-+ emit_insn(a4);
-+ }
-+ }
-+ }
-+
-+void
-+amigaos_alternate_frame_setup_f (int fsize)
-+ {
-+#if 0
-+ if (fsize < 128)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I%d,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\tlink %Ra5,%I%d:W\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")),
-+ fsize, -fsize);
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__link_a5_d0_f\n",
-+ fsize);
-+#endif
-+ }
-+
-+void
-+amigaos_alternate_frame_setup (int fsize)
-+ {
-+#if 0
-+ if (!fsize)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I0,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")));
-+ else if (fsize < 128)
-+ asm_fprintf (stream, "\tcmpl %s,%Rsp\n"
-+ "\tjcc 0f\n"
-+ "\tmoveq %I%d,%Rd0\n"
-+ "\tmoveq %I0,%Rd1\n"
-+ "\tjbsr %U__stkext_f\n"
-+ "0:\taddw %I%d,%Rsp\n",
-+ (flag_pic == 3 ? "a4@(___stk_limit:W)" :
-+ (flag_pic == 4 ? "a4@(___stk_limit:L)" :
-+ "___stk_limit")),
-+ fsize, -fsize);
-+ else
-+ asm_fprintf (stream, "\tmovel %I%d,%Rd0\n\tjbsr %U__sub_d0_sp_f\n",
-+ fsize);
-+#endif
-+ }
-+
-+#if 0
-+extern bool debug_recog(char const * txt, int which_alternative, int n, rtx * operands)
-+{
-+ fprintf(stderr, "%s: %d ", txt, which_alternative);
-+ for (int i = 0; i < n; ++i)
-+ print_rtl(stderr, operands[i]);
-+ fprintf(stderr, "\n--\n");
-+ return true;
-+}
-+#endif
-diff --git a/gcc/config/m68k/amigaos.h b/gcc/config/m68k/amigaos.h
-new file mode 100644
-index 000000000000..1b60ed633a3a
---- /dev/null
-+++ gcc/config/m68k/amigaos.h
-@@ -0,0 +1,504 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ *
-+ * This file is only included and used inside m68k.c to define the target.
-+ *
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra(a)student.uci.agh.edu.pl).
-+
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#ifndef TARGET_AMIGAOS
-+#define TARGET_AMIGAOS 1
-+#endif
-+
-+#if 0
-+/* The function name __transfer_from_trampoline is not actually used.
-+ The function definition just permits use of asm with operands"
-+ (though the operand list is empty). */
-+
-+#undef TRANSFER_FROM_TRAMPOLINE
-+
-+/* Call __flush_cache() after building the trampoline: it will call
-+ an appropriate OS cache-clearing routine. */
-+
-+#undef FINALIZE_TRAMPOLINE
-+#define FINALIZE_TRAMPOLINE(TRAMP) \
-+ emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__flush_cache"), \
-+ 0, VOIDmode, 2, (TRAMP), Pmode, \
-+ GEN_INT (TRAMPOLINE_SIZE), SImode)
-+
-+#endif
-+
-+/* Compile using the first 'm68k_regparm' data, address and float
-+ registers for arguments passing. */
-+/*#define SUBTARGET_OPTIONS { "regparm=", &m68k_regparm_string, \
-+ N_("Use this register count to pass arguments"), 0},*/
-+
-+
-+/* Nonzero if we need to generate special stack-allocating insns.
-+ On most systems they are not needed.
-+ When they are needed, also define ALTERNATE_ALLOCATE_STACK (see m68k.md)
-+ to perform the necessary actions. */
-+//#undef TARGET_ALTERNATE_ALLOCATE_STACK
-+//#define TARGET_ALTERNATE_ALLOCATE_STACK 0
-+
-+
-+/* Compile with stack extension. */
-+
-+#define MASK_STACKEXTEND 0x40000000 /* 1 << 30 */
-+#define TARGET_STACKEXTEND (((target_flags & MASK_STACKEXTEND) \
-+ && !lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \
-+ || lookup_attribute ("stackext", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-+
-+///* Compile with stack checking. */
-+//
-+#define MASK_STACKCHECK 0x20000000 /* 1 << 29 */
-+#define TARGET_STACKCHECK ((target_flags & MASK_STACKCHECK) \
-+ && !(target_flags & MASK_STACKEXTEND) \
-+ && !lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))) \
-+ && !lookup_attribute ("stackext", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl))))
-+
-+/* Compile with a4 restoring in public functions. */
-+
-+#define MASK_RESTORE_A4 0x10000000 /* 1 << 28 */
-+#define TARGET_RESTORE_A4 \
-+ ((target_flags & MASK_RESTORE_A4) && TREE_PUBLIC (current_function_decl))
-+
-+/* Compile with a4 restoring in all functions. */
-+
-+#define MASK_ALWAYS_RESTORE_A4 0x8000000 /* 1 << 27 */
-+#define TARGET_ALWAYS_RESTORE_A4 (target_flags & MASK_ALWAYS_RESTORE_A4)
-+
-+/* Provide a dummy entry for the '-msmall-code' switch. This is used by
-+ the assembler and '*_SPEC'. */
-+
-+#undef SUBTARGET_SWITCHES
-+#define SUBTARGET_SWITCHES \
-+ { "small-code", 0, \
-+ "" /* Undocumented. */ }, \
-+ { "stackcheck", MASK_STACKCHECK, \
-+ N_("Generate stack-check code") }, \
-+ { "no-stackcheck", - MASK_STACKCHECK, \
-+ N_("Do not generate stack-check code") }, \
-+ { "stackextend", MASK_STACKEXTEND, \
-+ N_("Generate stack-extension code") }, \
-+ { "no-stackextend", - MASK_STACKEXTEND, \
-+ N_("Do not generate stack-extension code") }, \
-+ { "fixedstack", - (MASK_STACKCHECK|MASK_STACKEXTEND), \
-+ N_("Do not generate stack-check/stack-extension code") }, \
-+ { "restore-a4", MASK_RESTORE_A4, \
-+ N_("Restore a4 in public functions") }, \
-+ { "no-restore-a4", - MASK_RESTORE_A4, \
-+ N_("Do not restore a4 in public functions") }, \
-+ { "always-restore-a4", MASK_ALWAYS_RESTORE_A4, \
-+ N_("Restore a4 in all functions") }, \
-+ { "no-always-restore-a4", - MASK_ALWAYS_RESTORE_A4, \
-+ N_("Do not restore a4 in all functions") }
-+
-+
-+/* Support sections in chip, fast memory, currently '.datachip',
'.datafast'
-+ * and '.datafar' to abs addressing with baserel. */
-+extern void
-+amiga_named_section (const char *name, unsigned int flags, tree decl);
-+
-+#undef TARGET_ASM_NAMED_SECTION
-+#define TARGET_ASM_NAMED_SECTION amiga_named_section
-+
-+/* Various ABI issues. */
-+
-+/* This is (almost;-) BSD, so it wants DBX format. */
-+#undef DBX_DEBUGGING_INFO
-+#define DBX_DEBUGGING_INFO
-+
-+/* GDB goes mad if it sees the function end marker. */
-+
-+#define NO_DBX_FUNCTION_END 1
-+
-+/* Allow folding division by zero. */
-+
-+#define REAL_INFINITY
-+
-+/* Don't try using XFmode since we don't have appropriate runtime software
-+ support. */
-+#undef LONG_DOUBLE_TYPE_SIZE
-+#define LONG_DOUBLE_TYPE_SIZE 64
-+
-+/* We use A4 for the PIC pointer, not A5, which is the framepointer. */
-+
-+#undef PIC_OFFSET_TABLE_REGNUM
-+#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? 12 : INVALID_REGNUM)
-+
-+/* Use A5 as framepointer instead of A6, since the AmigaOS ABI requires A6
-+ to be used as a shared library base pointer in direct library calls. */
-+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
-+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) (reg_names[(r)])
-+
-+/* The AmigaOS ABI does not define how structures should be returned, so,
-+ contrary to 'm68k.h', we prefer a multithread-safe solution. */
-+
-+#undef PCC_STATIC_STRUCT_RETURN
-+
-+/* Setup a default shell return value for those (gazillion..) programs that
-+ (inspite of ANSI-C) declare main() to be void (or even VOID...) and thus
-+ cause the shell to randomly caugh upon executing such programs (contrary
-+ to Unix, AmigaOS scripts are terminated with an error if a program returns
-+ with an error code above the `error' or even `failure' level
-+ (which is configurable with the FAILAT command)). */
-+
-+//+2004-06-24 Ulrich Weigand <uweigand(a)de.ibm.com>
-+//+
-+//+ * c-decl.c (finish_function): Do not check for DEFAULT_MAIN_RETURN.
-+//+ * system.h (DEFAULT_MAIN_RETURN): Poison.
-+//+ * doc/tm.texi (DEFAULT_MAIN_RETURN): Remove documentation.
-+//+
-+
-+//poison VAR
-+//#define DEFAULT_MAIN_RETURN c_expand_return (integer_zero_node)
-+
-+#undef WCHAR_TYPE
-+#define WCHAR_TYPE "unsigned short"
-+
-+/* XXX: section support */
-+#if 0
-+/* We define TARGET_ASM_NAMED_SECTION, but we don't support arbitrary sections,
-+ including '.gcc_except_table', so we emulate the standard behaviour. */
-+#undef TARGET_ASM_EXCEPTION_SECTION
-+#define TARGET_ASM_EXCEPTION_SECTION amiga_exception_section
-+
-+#undef TARGET_ASM_EH_FRAME_SECTION
-+#define TARGET_ASM_EH_FRAME_SECTION amiga_eh_frame_section
-+#endif
-+
-+/* Use sjlj exceptions because dwarf work only on elf targets */
-+#undef DWARF2_UNWIND_INFO
-+#define DWARF2_UNWIND_INFO 0
-+
-+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
-+
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
-+
-+/* GAS supports alignment up to 32768 bytes. */
-+#undef ASM_OUTPUT_ALIGN
-+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
-+do \
-+ { \
-+ if ((LOG) == 1) \
-+ fprintf ((FILE), "\t.even\n"); \
-+ else \
-+ fprintf ((FILE), "\t.align %d\n", (LOG)); \
-+ } \
-+while (0)
-+
-+#if 0
-+
-+/* Define this macro if references to a symbol must be treated
-+ differently depending on something about the variable or
-+ function named by the symbol (such as what section it is in).
-+
-+ The macro definition, if any, is executed immediately after the
-+ rtl for DECL or other node is created.
-+ The value of the rtl will be a `mem' whose address is a
-+ `symbol_ref'.
-+
-+ The usual thing for this macro to do is to a flag in the
-+ `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
-+ name string in the `symbol_ref' (if one bit is not enough
-+ information).
-+
-+ On the Amiga we use this to indicate if references to a symbol should be
-+ absolute or base relative. */
-+
-+#undef TARGET_ENCODE_SECTION_INFO
-+#define TARGET_ENCODE_SECTION_INFO amigaos_encode_section_info
-+
-+#define LIBCALL_ENCODE_SECTION_INFO(FUN) \
-+do \
-+ { \
-+ if (flag_pic >= 3) \
-+ SYMBOL_REF_FLAG (FUN) = 1; \
-+ } \
-+while (0)
-+
-+/* Select and switch to a section for EXP. */
-+
-+//#undef TARGET_ASM_SELECT_SECTION
-+//#define TARGET_ASM_SELECT_SECTION amigaos_select_section
-+
-+/* Preserve A4 for baserel code if necessary. */
-+
-+#define EXTRA_SAVE_REG(REGNO) \
-+do { \
-+ if (flag_pic && flag_pic >= 3 && REGNO ==
PIC_OFFSET_TABLE_REGNUM \
-+ && amigaos_restore_a4()) \
-+ return true; \
-+} while (0)
-+
-+/* Predicate for ALTERNATE_PIC_SETUP. */
-+
-+#define HAVE_ALTERNATE_PIC_SETUP (flag_pic >= 3)
-+
-+/* Make a4 point at data hunk. */
-+
-+#define ALTERNATE_PIC_SETUP(STREAM) \
-+ (amigaos_alternate_pic_setup (STREAM))
-+
-+/* Attribute support. */
-+
-+/* Generate the test of d0 before return to set cc register in 'interrupt'
-+ function. */
-+
-+#define EPILOGUE_END_HOOK(STREAM) \
-+do \
-+ { \
-+ if (lookup_attribute ("interrupt", \
-+ TYPE_ATTRIBUTES (TREE_TYPE (current_function_decl)))) \
-+ asm_fprintf ((STREAM), "\ttstl %Rd0\n"); \
-+ } \
-+while (0)
-+
-+
-+/* Stack checking and automatic extension support. */
-+
-+#define PROLOGUE_BEGIN_HOOK(STREAM, FSIZE) \
-+ (amigaos_prologue_begin_hook ((STREAM), (FSIZE)))
-+
-+#define HAVE_ALTERNATE_FRAME_DESTR_F(FSIZE) \
-+ (TARGET_STACKEXTEND && current_function_calls_alloca)
-+
-+#define ALTERNATE_FRAME_DESTR_F(STREAM, FSIZE) \
-+ (asm_fprintf ((STREAM), "\tjra %U__unlk_a5_rts\n"))
-+
-+#define HAVE_ALTERNATE_RETURN \
-+ (TARGET_STACKEXTEND && frame_pointer_needed && \
-+ current_function_calls_alloca)
-+
-+#define ALTERNATE_RETURN(STREAM)
-+
-+#if 0
-+#define HAVE_restore_stack_nonlocal TARGET_STACKEXTEND
-+#define gen_restore_stack_nonlocal gen_stack_cleanup_call
-+
-+#define HAVE_restore_stack_function TARGET_STACKEXTEND
-+#define gen_restore_stack_function gen_stack_cleanup_call
-+
-+#define HAVE_restore_stack_block TARGET_STACKEXTEND
-+#define gen_restore_stack_block gen_stack_cleanup_call
-+
-+#undef TARGET_ALTERNATE_ALLOCATE_STACK
-+#define TARGET_ALTERNATE_ALLOCATE_STACK 1
-+
-+#define ALTERNATE_ALLOCATE_STACK(OPERANDS) \
-+do \
-+ { \
-+ amigaos_alternate_allocate_stack (OPERANDS); \
-+ DONE; \
-+ } \
-+while (0)
-+#endif
-+
-+/* begin-GG-local: dynamic libraries */
-+
-+extern int amigaos_do_collecting (void);
-+extern void amigaos_gccopts_hook (const char *);
-+extern void amigaos_libname_hook (const char* arg);
-+extern void amigaos_collect2_cleanup (void);
-+extern void amigaos_prelink_hook (const char **, int *);
-+extern void amigaos_postlink_hook (const char *);
-+
-+/* This macro is used to check if all collect2 facilities should be used.
-+ We need a few special ones, like stripping after linking. */
-+
-+#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE) //new
-+
-+/* This macro is called in collect2 for every GCC argument name.
-+ ARG is a part of commandline (without '\0' at the end). */
-+
-+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
-+
-+/* This macro is called in collect2 for every ld's "-l" or "*.o"
or "*.a"
-+ argument. ARG is a complete argument, with '\0' at the end. */
-+
-+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
-+
-+/* This macro is called at collect2 exit, to clean everything up. */
-+
-+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
-+
-+/* This macro is called just before the first linker invocation.
-+ LD1_ARGV is "char** argv", which will be passed to "ld". STRIP
is an
-+ *address* of "strip_flag" variable. */
-+
-+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
-+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
-+
-+/* This macro is called just after the first linker invocation, in place of
-+ "nm" and "ldd". OUTPUT_FILE is the executable's filename.
*/
-+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
-+
-+#endif
-+
-+/* begin-GG-local: explicit register specification for parameters */
-+
-+/* Note: this is an extension of m68k_args */
-+
-+
-+#undef CLASS_MAX_NREGS
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+ ((CLASS) == FP_REGS ? GET_MODE_NUNITS (MODE) \
-+ : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-+
-+
-+/*
-+ On the m68k, this is a structure:
-+ num_of_regs: number of data, address and float registers to use for
-+ arguments passing (if it's 2, than pass arguments in d0, d1, a0, a1,
-+ fp0 and fp1). 0 - pass everything on stack. vararg calls are
-+ always passed entirely on stack.
-+ regs_already_used: bitmask of the already used registers.
-+ last_arg_reg - register number of the most recently passed argument.
-+ -1 if passed on stack.
-+ last_arg_len - number of registers used by the most recently passed
-+ argument.
-+*/
-+
-+extern void amigaos_init_cumulative_args (CUMULATIVE_ARGS *cum, tree);
-+extern void amigaos_function_arg_advance (cumulative_args_t, machine_mode, const_tree,
bool);
-+extern rtx amigaos_function_arg (cumulative_args_t, machine_mode, const_tree, bool);
-+extern cumulative_args_t amigaos_pack_cumulative_args (CUMULATIVE_ARGS *);
-+extern int amigaos_comp_type_attributes (const_tree, const_tree);
-+extern tree amigaos_handle_type_attribute(tree *, tree, tree, int, bool*);
-+
-+/* Update the data in CUM to advance over an argument
-+ of mode MODE and data type TYPE.
-+ (TYPE is null for libcalls where that information may not be available.) */
-+
-+#undef TARGET_FUNCTION_ARG_ADVANCE
-+#define TARGET_FUNCTION_ARG_ADVANCE amigaos_function_arg_advance
-+
-+/* A C expression that controls whether a function argument is passed
-+ in a register, and which register. */
-+
-+#undef TARGET_FUNCTION_ARG
-+#define TARGET_FUNCTION_ARG amigaos_function_arg
-+
-+#undef TARGET_PACK_CUMULATIVE_ARGS
-+#define TARGET_PACK_CUMULATIVE_ARGS(CUM) \
-+ (amigaos_pack_cumulative_args(&(CUM)))
-+
-+#undef TARGET_COMP_TYPE_ATTRIBUTES
-+#define TARGET_COMP_TYPE_ATTRIBUTES amigaos_comp_type_attributes
-+
-+
-+/* end-GG-local */
-+
-+#undef SUBTARGET_OVERRIDE_OPTIONS
-+#define SUBTARGET_OVERRIDE_OPTIONS \
-+do \
-+ { \
-+ if (flag_resident) \
-+ { \
-+ if (flag_pic) \
-+ error ("-fbaserel and -resident are mutual exclusiv\n"); \
-+ flag_pic = flag_resident; \
-+ } \
-+ if (!TARGET_68020 && flag_pic==4) \
-+ error ("-fbaserel32 is not supported on the 68000 or 68010\n"); \
-+ if (amigaos_regparm > 0 && amigaos_regparm > AMIGAOS_MAX_REGPARM) \
-+ error ("-mregparm=x with 1 <= x <= %d\n", AMIGAOS_MAX_REGPARM);
\
-+ } \
-+while (0)
-+
-+/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-+ affects_type_identity } */
-+#define SUBTARGET_ATTRIBUTES \
-+ { "asmregs", 0, 0, false, false, false, 0, true }, \
-+ { "chip", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "fast", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "far", 0, 0, false, true, false, amigaos_handle_type_attribute, false },
\
-+ { "saveds", 0, 0, false, true, true, amigaos_handle_type_attribute, false },
\
-+ { "regparm", 1, 1, false, true, true, amigaos_handle_type_attribute,\
-+ true }, \
-+ { "stkparm", 0, 0, false, true, true, amigaos_handle_type_attribute,\
-+ true },
-+
-+#define GOT_SYMBOL_NAME ""
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS amigaos_rtx_costs
-+bool
-+amigaos_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+
-+#undef TARGET_STRUCT_VALUE_RTX
-+#define TARGET_STRUCT_VALUE_RTX amigaos_struct_value_rtx
-+rtx
-+amigaos_struct_value_rtx(tree fntype,
-+ int incoming ATTRIBUTE_UNUSED);
-+
-+#undef TARGET_STATIC_CHAIN
-+#define TARGET_STATIC_CHAIN amigaos_static_chain_rtx
-+rtx
-+amigaos_static_chain_rtx(const_tree fntype,
-+ bool incoming ATTRIBUTE_UNUSED);
-+
-+
-+extern bool
-+amigaos_legitimate_src (rtx src);
-+
-+extern void
-+amigaos_restore_a4 (void);
-+
-+extern void
-+amigaos_alternate_frame_setup_f (int fsize);
-+
-+extern void
-+amigaos_alternate_frame_setup (int fsize);
-+
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP_F(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP_F(FSIZE) \
-+ (amigaos_alternate_frame_setup_f ((FSIZE)))
-+
-+#define HAVE_ALTERNATE_FRAME_SETUP(FSIZE) TARGET_STACKEXTEND
-+
-+#define ALTERNATE_FRAME_SETUP(FSIZE) \
-+ (amigaos_alternate_frame_setup ((FSIZE)))
-+
-+#undef TARGET_INSERT_ATTRIBUTES
-+#define TARGET_INSERT_ATTRIBUTES amiga_insert_attribute
-+
-+void
-+amiga_insert_attribute (tree decl, tree * attr);
-diff --git a/gcc/config/m68k/amigaos.opt b/gcc/config/m68k/amigaos.opt
-new file mode 100644
-index 000000000000..07406d27a777
---- /dev/null
-+++ gcc/config/m68k/amigaos.opt
-@@ -0,0 +1,63 @@
-+
-+mregparm=
-+Target RejectNegative Var(amigaos_regparm) Joined UInteger Init(-1)
-+Pass arguments through registers.
-+
-+noixemul
-+Target RejectNegative
-+Do not use ixemul.library - use libnix instead to link
-+
-+ramiga-lib
-+Target RejectNegative
-+Use libinit.o as start file
-+
-+ramiga-libr
-+Target RejectNegative
-+Use libinitr.o as start file
-+
-+ramiga-dev
-+Target RejectNegative
-+Use devinit.o as start file
-+
-+msmall-code
-+Target RejectNegative Var(flag_smallcode,1)
-+small code model
-+
-+fbaserel
-+Target Report Var(flag_pic,3)
-+data is addressed relative to a4
-+
-+fbaserel32
-+Target Report Var(flag_pic,4)
-+data is addressed relative to a4 with 32 bit offsets
-+
-+resident
-+Target Common Report Var(flag_resident,3)
-+data is addressed relative to a4, linked as resident
-+
-+resident32
-+Target Common Report Var(flag_resident,4)
-+data is addressed relative to a4 with 32 bit offsets, linked as resident
-+
-+mcrt=
-+Target RejectNegative Var(amigaos_crt) Joined
-+Specify startup binary
-+
-+fbbb=
-+Target RejectNegative Report Var(string_bbb_opts) Joined
-+-fbbb=Enable Bebbo's optimizations.
-++ enable all optimizations
-+a commute add move instructions
-+b use register for base addresses
-+c convert load const and compare into a sub
-+e eliminate dead assignments + redundant loads
-+f shrink stack frame
-+i use post increment on addresses
-+m merge add and move statements
-+p propagate move assignment pairs out of loops
-+r register renaming to maybe save registers
-+s a strcpy optimization
-+v be verbose
-+V be very verbose
-+x dump insns
-+Default: -fbbb=+ which yields -fbbb=abcefimprs
-diff --git a/gcc/config/m68k/constraints.md b/gcc/config/m68k/constraints.md
-index b62120895304..1223852570c1 100644
---- gcc/config/m68k/constraints.md
-+++ gcc/config/m68k/constraints.md
-@@ -1,5 +1,5 @@
- ;; Constraint definitions for m68k
--;; Copyright (C) 2007-2016 Free Software Foundation, Inc.
-+;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
-
- ;; This file is part of GCC.
-
-diff --git a/gcc/config/m68k/host-amigaos.c b/gcc/config/m68k/host-amigaos.c
-new file mode 100755
-index 000000000000..8c72d516a378
---- /dev/null
-+++ gcc/config/m68k/host-amigaos.c
-@@ -0,0 +1,42 @@
-+/* AmigaOS/m68k host-specific hook definitions.
-+ Copyright (C) 2003 Free Software Foundation, Inc.
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify it under
-+the terms of the GNU General Public License as published by the Free
-+Software Foundation; either version 2, or (at your option) any later
-+version.
-+
-+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-+WARRANTY; without even the implied warranty of MERCHANTABILITY or
-+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-+for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to the Free
-+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-+02111-1307, USA. */
-+
-+
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "hosthooks.h"
-+#include "hosthooks-def.h"
-+#include "toplev.h"
-+
-+static void * amigaos_m68k_gt_pch_get_address (size_t);
-+
-+/* Return the address of the PCH address space, if the PCH will fit in it. */
-+
-+static void *
-+amigaos_m68k_gt_pch_get_address (size_t sz ATTRIBUTE_UNUSED)
-+{
-+ fatal_error ("PCH not supported\n");
-+}
-+
-+#undef HOST_HOOKS_GT_PCH_GET_ADDRESS
-+#define HOST_HOOKS_GT_PCH_GET_ADDRESS amigaos_m68k_gt_pch_get_address
-+
-+const struct host_hooks host_hooks = HOST_HOOKS_INITIALIZER;
-\ No newline at end of file
-diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
-index 03f474e1b63c..4533427db7a7 100644
---- gcc/config/m68k/m68k.c
-+++ gcc/config/m68k/m68k.c
-@@ -166,7 +166,10 @@ static bool m68k_save_reg (unsigned int regno, bool
interrupt_handler);
- static bool m68k_ok_for_sibcall_p (tree, tree);
- static bool m68k_tls_symbol_p (rtx);
- static rtx m68k_legitimize_address (rtx, rtx, machine_mode);
--static bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
-+#ifndef TARGET_AMIGA
-+static
-+#endif
-+bool m68k_rtx_costs (rtx, machine_mode, int, int, int *, bool);
- #if M68K_HONOR_TARGET_STRICT_ALIGNMENT
- static bool m68k_return_in_memory (const_tree, const_tree);
- #endif
-@@ -174,10 +177,12 @@ static void m68k_output_dwarf_dtprel (FILE *, int, rtx)
ATTRIBUTE_UNUSED;
- static void m68k_trampoline_init (rtx, tree, rtx);
- static int m68k_return_pops_args (tree, tree, int);
- static rtx m68k_delegitimize_address (rtx);
-+#ifndef TARGET_AMIGA
- static void m68k_function_arg_advance (cumulative_args_t, machine_mode,
- const_tree, bool);
- static rtx m68k_function_arg (cumulative_args_t, machine_mode,
- const_tree, bool);
-+#endif
- static bool m68k_cannot_force_const_mem (machine_mode mode, rtx x);
- static bool m68k_output_addr_const_extra (FILE *, rtx);
- static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-@@ -186,7 +191,11 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
-
- #if INT_OP_GROUP == INT_OP_DOT_WORD
- #undef TARGET_ASM_ALIGNED_HI_OP
-+#ifndef TARGET_AMIGAOS_VASM
- #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-+#else
-+#define TARGET_ASM_ALIGNED_HI_OP "\tdc.w\t"
-+#endif
- #endif
-
- #if INT_OP_GROUP == INT_OP_NO_DOT
-@@ -322,6 +331,10 @@ static void m68k_init_sync_libfuncs (void) ATTRIBUTE_UNUSED;
- #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
- #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 128
-
-+#ifdef TARGET_AMIGA
-+#include "amigaos.h"
-+#endif
-+
- static const struct attribute_spec m68k_attribute_table[] =
- {
- /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-@@ -332,6 +345,9 @@ static const struct attribute_spec m68k_attribute_table[] =
- m68k_handle_fndecl_attribute, false },
- { "interrupt_thread", 0, 0, true, false, false,
- m68k_handle_fndecl_attribute, false },
-+#ifdef SUBTARGET_ATTRIBUTES
-+ SUBTARGET_ATTRIBUTES
-+#endif
- { NULL, 0, 0, false, false, false, NULL, false }
- };
-
-@@ -340,11 +356,21 @@ struct gcc_target targetm = TARGET_INITIALIZER;
- /* Base flags for 68k ISAs. */
- #define FL_FOR_isa_00 FL_ISA_68000
- #define FL_FOR_isa_10 (FL_FOR_isa_00 | FL_ISA_68010)
--/* FL_68881 controls the default setting of -m68881. gcc has traditionally
-+/* "FL_68881 controls the default setting of -m68881. gcc has traditionally
- generated 68881 code for 68020 and 68030 targets unless explicitly told
-- not to. */
-+ not to."
-+
-+ This is not true at least for the AMIGA.
-+ gcc 2.93 does not set the 68881 flag.
-+
-+ */
-+#ifdef TARGET_AMIGA
-+#define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
-+ | FL_BITFIELD | FL_CAS)
-+#else
- #define FL_FOR_isa_20 (FL_FOR_isa_10 | FL_ISA_68020 \
- | FL_BITFIELD | FL_68881 | FL_CAS)
-+#endif
- #define FL_FOR_isa_40 (FL_FOR_isa_20 | FL_ISA_68040)
- #define FL_FOR_isa_cpu32 (FL_FOR_isa_10 | FL_ISA_68020)
-
-@@ -545,7 +571,7 @@ m68k_option_override (void)
- : (m68k_cpu_flags & FL_COLDFIRE) != 0 ? FPUTYPE_COLDFIRE
- : FPUTYPE_68881);
-
-- /* Sanity check to ensure that msep-data and mid-sahred-library are not
-+ /* Sanity check to ensure that msep-data and mid-shared-library are not
- * both specified together. Doing so simply doesn't make sense.
- */
- if (TARGET_SEP_DATA && TARGET_ID_SHARED_LIBRARY)
-@@ -556,7 +582,7 @@ m68k_option_override (void)
- * -fpic but it hasn't been tested properly.
- */
- if (TARGET_SEP_DATA || TARGET_ID_SHARED_LIBRARY)
-- flag_pic = 2;
-+ flag_pic = TARGET_68020 ? 2 : 1;
-
- /* -mpcrel -fPIC uses 32-bit pc-relative displacements. Raise an
- error if the target does not support them. */
-@@ -569,11 +595,15 @@ m68k_option_override (void)
- if (TARGET_PCREL && flag_pic == 0)
- flag_pic = 1;
-
-- if (!flag_pic)
-+ /* SBF: use normal jumps/calls with baserel(32) modes. */
-+ if (!flag_pic || flag_pic > 2)
- {
- m68k_symbolic_call_var = M68K_SYMBOLIC_CALL_JSR;
--
-+#ifndef TARGET_AMIGAOS_VASM
- m68k_symbolic_jump = "jra %a0";
-+#else
-+ m68k_symbolic_jump = "jmp %a0";
-+#endif
- }
- else if (TARGET_ID_SHARED_LIBRARY)
- /* All addresses must be loaded from the GOT. */
-@@ -866,8 +896,9 @@ m68k_save_reg (unsigned int regno, bool interrupt_handler)
- {
- if (crtl->saves_all_registers)
- return true;
-+ /* SBF: do not save the PIC_REG with baserel(32) modes. */
- if (crtl->uses_pic_offset_table)
-- return true;
-+ return flag_pic < 3;
- /* Reload may introduce constant pool references into a function
- that thitherto didn't need a PIC register. Note that the test
- above will not catch that case because we will only set
-@@ -978,6 +1009,8 @@ m68k_set_frame_related (rtx_insn *insn)
-
- /* Emit RTL for the "prologue" define_expand. */
-
-+extern void amiga_emit_regparm_clobbers(void);
-+
- void
- m68k_expand_prologue (void)
- {
-@@ -986,6 +1019,10 @@ m68k_expand_prologue (void)
-
- m68k_compute_frame_layout ();
-
-+#ifdef TARGET_AMIGA
-+ amiga_emit_regparm_clobbers();
-+#endif
-+
- if (flag_stack_usage_info)
- current_function_static_stack_size
- = current_frame.size + current_frame.offset;
-@@ -1021,6 +1058,11 @@ m68k_expand_prologue (void)
-
- if (frame_pointer_needed)
- {
-+#ifdef TARGET_AMIGA
-+ if (HAVE_ALTERNATE_FRAME_SETUP_F (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP_F (fsize_with_regs);
-+ else
-+#endif
- if (fsize_with_regs == 0 && TUNE_68040)
- {
- /* On the 68040, two separate moves are faster than link.w 0. */
-@@ -1030,6 +1072,10 @@ m68k_expand_prologue (void)
- m68k_set_frame_related (emit_move_insn (frame_pointer_rtx,
- stack_pointer_rtx));
- }
-+#ifdef TARGET_AMIGA
-+ else if (HAVE_ALTERNATE_FRAME_SETUP (fsize_with_regs))
-+ ALTERNATE_FRAME_SETUP (fsize_with_regs);
-+#endif
- else if (fsize_with_regs < 0x8000 || TARGET_68020)
- m68k_set_frame_related
- (emit_insn (gen_link (frame_pointer_rtx,
-@@ -1127,9 +1173,14 @@ m68k_expand_prologue (void)
- current_frame.reg_mask, true, true));
- }
-
-+ /* SBF: do not load the PIC_REG with baserel(32) */
- if (!TARGET_SEP_DATA
-- && crtl->uses_pic_offset_table)
-+ && crtl->uses_pic_offset_table && flag_pic < 3)
- emit_insn (gen_load_got (pic_offset_table_rtx));
-+
-+#ifdef TARGET_AMIGA
-+ amigaos_restore_a4 ();
-+#endif
- }
-
- /* Return true if a simple (return) instruction is sufficient for this
-@@ -1419,6 +1470,7 @@ m68k_ok_for_sibcall_p (tree decl, tree exp)
- return false;
- }
-
-+#ifndef TARGET_AMIGA
- /* On the m68k all args are always pushed. */
-
- static rtx
-@@ -1440,6 +1492,7 @@ m68k_function_arg_advance (cumulative_args_t cum_v, machine_mode
mode,
- ? (GET_MODE_SIZE (mode) + 3) & ~3
- : (int_size_in_bytes (type) + 3) & ~3);
- }
-+#endif
-
- /* Convert X to a legitimate function call memory reference and return the
- result. */
-@@ -1796,13 +1849,21 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx_insn
*insn, int signpos
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_Z_IN_NOT_N | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- if (count == 2 && DATA_REG_P (operands[1])
- && next_insn_tests_no_inequality (insn))
- {
- cc_status.flags = CC_NOT_NEGATIVE | CC_INVERTED | CC_NO_OVERFLOW;
-+#ifndef TARGET_AMIGAOS_VASM
- return "move%.w %1,%%ccr";
-+#else
-+ return "move%.w %1,ccr";
-+#endif
- }
- /* count == 1 followed by bvc/bvs and
- count == 0 followed by bcc/bcs are also possible, but need
-@@ -1921,10 +1982,12 @@ m68k_legitimate_constant_address_p (rtx x, unsigned int reach,
bool strict_p)
- if (!CONSTANT_ADDRESS_P (x))
- return false;
-
-- if (flag_pic
-+ if (flag_pic && flag_pic < 3
- && !(strict_p && TARGET_PCREL)
- && symbolic_operand (x, VOIDmode))
-- return false;
-+ {
-+ return false;
-+ }
-
- if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P && reach > 1)
- {
-@@ -2111,6 +2174,18 @@ m68k_legitimate_address_p (machine_mode mode, rtx x, bool
strict_p)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ if (MEM_P(x))
-+ return false;
-+ /* SBF: the baserel(32) const plus pic_ref, symbol is an address. */
-+ if (amiga_is_const_pic_ref(x))
-+ return true;
-+
-+ if (!amigaos_legitimate_src(x))
-+ return false;
-+
-+#endif
-+
- return m68k_decompose_address (mode, x, strict_p, &address);
- }
-
-@@ -2131,7 +2206,11 @@ m68k_legitimate_mem_p (rtx x, struct m68k_address *address)
- bool
- m68k_legitimate_constant_p (machine_mode mode, rtx x)
- {
-- return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x);
-+ return mode != XFmode && !m68k_illegitimate_symbolic_constant_p (x)
-+#ifdef TARGET_AMIGA
-+ && amigaos_legitimate_src (x)
-+#endif
-+ ;
- }
-
- /* Return true if X matches the 'Q' constraint. It must be a memory
-@@ -2172,6 +2251,8 @@ m68k_get_gp (void)
- if (pic_offset_table_rtx == NULL_RTX)
- pic_offset_table_rtx = gen_rtx_REG (Pmode, PIC_REG);
-
-+// debug_rtx(pic_offset_table_rtx);
-+
- crtl->uses_pic_offset_table = 1;
-
- return pic_offset_table_rtx;
-@@ -2442,9 +2523,37 @@ legitimize_pic_address (rtx orig, machine_mode mode
ATTRIBUTE_UNUSED,
- if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
- {
- gcc_assert (reg);
-+ if (flag_pic < 3)
-+ {
-+ pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-+ pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+ }
-+ #ifdef TARGET_AMIGA
-+ else
-+ {
-+
-+ /* SBF: Does the symbol use common or bss and qualifies for pic_reg?
-+ * Do not ref to .text via pic_reg!
-+ */
-+ tree decl;
-+ if (GET_CODE (orig) == SYMBOL_REF && !orig->frame_related &&
!SYMBOL_REF_FUNCTION_P(orig)
-+ && (decl = SYMBOL_REF_DECL (orig)) && !(DECL_SECTION_NAME(decl))
-+ && !decl->common.typed.base.readonly_flag
-+ && !decl->decl_with_vis.in_text_section)
-+ {
-
-- pic_ref = m68k_wrap_symbol_into_got_ref (orig, RELOC_GOT, reg);
-- pic_ref = m68k_move_to_reg (pic_ref, orig, reg);
-+ /* SBF: unfortunately using the wrapped symbol without MEM does not work.
-+ * The pic_ref reference gets decomposed and leads to no working code.
-+ */
-+ pic_ref = m68k_wrap_symbol (pic_ref, RELOC_GOT, m68k_get_gp (), reg);
-+
-+ /* SBF: adding const avoids decomposing. */
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+ else
-+ pic_ref = gen_rtx_CONST (Pmode, pic_ref);
-+ }
-+#endif
- }
- else if (GET_CODE (orig) == CONST)
- {
-@@ -2463,7 +2572,8 @@ legitimize_pic_address (rtx orig, machine_mode mode
ATTRIBUTE_UNUSED,
- orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
-
-- if (GET_CODE (orig) == CONST_INT)
-+ /* SBF: use normal plus and rely on optimizer with baserel(32). */
-+ if (flag_pic < 3 && GET_CODE (orig) == CONST_INT)
- pic_ref = plus_constant (Pmode, base, INTVAL (orig));
- else
- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
-@@ -2787,7 +2897,10 @@ const_int_cost (HOST_WIDE_INT i)
- }
- }
-
--static bool
-+#ifndef TARGET_AMIGA
-+static
-+#endif
-+bool
- m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- int opno ATTRIBUTE_UNUSED,
- int *total, bool speed ATTRIBUTE_UNUSED)
-@@ -2863,6 +2976,7 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = COSTS_N_INSNS (TARGET_COLDFIRE ? 2 : 3);
- return true;
- }
-+
- return false;
-
- case ASHIFT:
-@@ -2931,6 +3045,25 @@ m68k_rtx_costs (rtx x, machine_mode mode, int outer_code,
- *total = 0;
- return false;
-
-+ case MEM:
-+ {
-+ /* simple but not exact */
-+ rtx y = XEXP(x, 0);
-+ int yc = GET_CODE(y);
-+ if (yc == REG || yc == PRE_INC || yc == POST_INC || yc == POST_DEC)
-+ *total += 4;
-+ else
-+ if (yc == PRE_DEC)
-+ *total += 6;
-+ else
-+ *total += 8;
-+
-+ if (mode != QImode && mode != QImode)
-+ *total += 4;
-+
-+ return true;
-+ }
-+
- default:
- return false;
- }
-@@ -4456,7 +4589,9 @@ print_operand (FILE *file, rtx op, int letter)
- else if (letter == 'p')
- {
- output_addr_const (file, op);
-- if (!(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
-+ /* SBF: do not add @PLTPC with baserel(32). */
-+ if (flag_pic < 3
-+ && !(GET_CODE (op) == SYMBOL_REF && SYMBOL_REF_LOCAL_P (op)))
- fprintf (file, "@PLTPC");
- }
- else if (GET_CODE (op) == REG)
-@@ -4475,34 +4610,52 @@ print_operand (FILE *file, rtx op, int letter)
- && CONSTANT_ADDRESS_P (XEXP (op, 0))
- && !(GET_CODE (XEXP (op, 0)) == CONST_INT
- && INTVAL (XEXP (op, 0)) < 0x8000
-- && INTVAL (XEXP (op, 0)) >= -0x8000))
-- fprintf (file, MOTOROLA ? ".l" : ":l");
-+ && INTVAL (XEXP (op, 0)) >= -0x8000)
-+#ifdef TARGET_AMIGA
-+/* SBF: Do not append some 'l' with baserel(32). */
-+ && !amiga_is_const_pic_ref(XEXP(op, 0))
-+#endif
-+ )
-+ fprintf (file, MOTOROLA ? ".l" : ":l");
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == SFmode)
- {
- long l;
- REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx", l & 0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx", l & 0xFFFFFFFF);
-+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == XFmode)
- {
- long l[3];
- REAL_VALUE_TO_TARGET_LONG_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
- l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx%08lx%08lx", l[0] & 0xFFFFFFFF,
-+ l[1] & 0xFFFFFFFF, l[2] & 0xFFFFFFFF);
-+#endif
- }
- else if (GET_CODE (op) == CONST_DOUBLE && GET_MODE (op) == DFmode)
- {
- long l[2];
- REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (op), l);
-+#ifndef TARGET_AMIGAOS_VASM
- asm_fprintf (file, "%I0x%lx%08lx", l[0] & 0xFFFFFFFF, l[1] &
0xFFFFFFFF);
-+#else
-+ asm_fprintf (file, "%I$%lx%08lx", l[0] & 0xFFFFFFFF, l[1] &
0xFFFFFFFF);
-+#endif
- }
- else
- {
- /* Use `print_operand_address' instead of `output_addr_const'
- to ensure that we print relevant PIC stuff. */
- asm_fprintf (file, "%I");
-- if (TARGET_PCREL
-+ if ((TARGET_PCREL || flag_pic > 2)
- && (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST))
- print_operand_address (file, op);
- else
-@@ -4521,7 +4674,19 @@ m68k_get_reloc_decoration (enum m68k_reloc reloc)
- switch (reloc)
- {
- case RELOC_GOT:
-- if (MOTOROLA)
-+ /* SBF: add the proper extension for baserel relocs with baserel(32). */
-+ if (TARGET_AMIGA)
-+ {
-+ if (flag_pic == 1)
-+ return ".w";
-+ else if (flag_pic == 3)
-+ return ":W";
-+ else if (flag_pic == 4)
-+ return ":L";
-+ else
-+ return "";
-+ }
-+ if (MOTOROLA)
- {
- if (flag_pic == 1 && TARGET_68020)
- return "(a)GOT.w";
-@@ -4671,8 +4836,58 @@ print_operand_address (FILE *file, rtx addr)
- {
- struct m68k_address address;
-
-+#ifdef TARGET_AMIGA
-+ /*
-+ * SBF: remove the const wrapper.
-+ */
-+ if (amiga_is_const_pic_ref(addr))
-+ {
-+ /* handle (plus (unspec ) (const_int) */
-+ rtx *x = &addr;
-+ while (GET_CODE(*x) != PLUS)
-+ x = &XEXP(*x, 0);
-+
-+ x = &XEXP(*x, 1); // CONST
-+ if (GET_CODE(*x) == CONST)
-+ x = &XEXP(*x, 0);
-+
-+ /* if there is a plus - swap it.
-+ * we want n+symbol:W (not symbol:W+n)
-+ */
-+ if (GET_CODE(*x) == PLUS)
-+ {
-+ rtx plus = *x;
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(plus, 1)));
-+
-+ *x = XEXP(plus, 0);
-+ print_operand_address(file, XEXP(addr, 0));
-+ *x = plus;
-+ }
-+ else
-+ print_operand_address(file, XEXP(addr, 0));
-+
-+ return;
-+ }
-+ if (GET_CODE(addr) == PLUS && amiga_is_const_pic_ref(XEXP(addr, 0)))
-+ {
-+ fprintf (file, "%d+", (int) INTVAL (XEXP(addr, 1)));
-+ print_operand_address(file, XEXP(XEXP(addr, 0),0));
-+ return;
-+ }
-+
-+
-+ if (symbolic_operand(addr, VOIDmode))
-+ {
-+ memset (&address, 0, sizeof (address));
-+ address.offset = addr;
-+ }
-+ else
-+#endif
- if (!m68k_decompose_address (QImode, addr, true, &address))
-- gcc_unreachable ();
-+ {
-+ debug_rtx(addr);
-+ gcc_unreachable ();
-+ }
-
- if (address.code == PRE_DEC)
- fprintf (file, MOTOROLA ? "-(%s)" : "%s@-",
-@@ -4714,6 +4929,14 @@ print_operand_address (FILE *file, rtx addr)
- }
- else
- output_addr_const (file, addr);
-+
-+#ifdef TARGET_AMIGA
-+ if (SYMBOL_REF_FUNCTION_P(addr))
-+ {
-+ if (flag_smallcode)
-+ asm_fprintf(file, ":w(pc)");
-+ }
-+#endif
- }
- }
- else
-@@ -5155,7 +5378,9 @@ m68k_hard_regno_rename_ok (unsigned int old_reg ATTRIBUTE_UNUSED,
-
- /* Value is true if hard register REGNO can hold a value of machine-mode
- MODE. On the 68000, we let the cpu registers can hold any mode, but
-- restrict the 68881 registers to floating-point modes. */
-+ restrict the 68881 registers to floating-point modes.
-+ SBF: Disallow the frame pointer register, if the frame pointer is used.
-+ */
-
- bool
- m68k_regno_mode_ok (int regno, machine_mode mode)
-@@ -5169,7 +5394,7 @@ m68k_regno_mode_ok (int regno, machine_mode mode)
- else if (ADDRESS_REGNO_P (regno))
- {
- if (regno + GET_MODE_SIZE (mode) / 4 <= 16)
-- return true;
-+ return !frame_pointer_needed || regno != FRAME_POINTER_REGNUM;
- }
- else if (FP_REGNO_P (regno))
- {
-@@ -5190,6 +5415,13 @@ m68k_secondary_reload_class (enum reg_class rclass,
- machine_mode mode, rtx x)
- {
- int regno;
-+#ifdef TARGET_AMIGA
-+ /* SBF: check for baserel's const pic_ref
-+ * and return ADDR_REGS or NO_REGS
-+ */
-+ if (!MEM_P(x) && amiga_is_const_pic_ref(x))
-+ return rclass == ADDR_REGS ? NO_REGS : ADDR_REGS;
-+#endif
-
- regno = true_regnum (x);
-
-diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
-index 2aa858fa23b5..442a84e6a883 100644
---- gcc/config/m68k/m68k.h
-+++ gcc/config/m68k/m68k.h
-@@ -204,7 +204,11 @@ along with GCC; see the file COPYING3. If not see
- #define INT_OP_DC 3 /* dc.b, dc.w, dc.l */
-
- /* Set the default. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define INT_OP_GROUP INT_OP_DOT_WORD
-+#else
-+#define INT_OP_GROUP INT_OP_DC
-+#endif
-
- /* Bit values used by m68k-devices.def to identify processor capabilities. */
- #define FL_BITFIELD (1 << 0) /* Support bitfield instructions. */
-@@ -378,14 +382,13 @@ along with GCC; see the file COPYING3. If not see
- { /* d0/d1/a0/a1 */ \
- 0, 1, 8, 9, \
- /* d2-d7 */ \
-- 2, 3, 4, 5, 6, 7, \
-+ 2, 10, 3, 11, 4, 5, 6, 7, \
- /* a2-a7/arg */ \
-- 10, 11, 12, 13, 14, 15, 24, \
-+ 12, 13, 14, 15, 24, \
- /* fp0-fp7 */ \
- 16, 17, 18, 19, 20, 21, 22, 23\
- }
-
--
- /* On the m68k, ordinary registers hold 32 bits worth;
- for the 68881 registers, a single register is always enough for
- anything that can be stored in them at all. */
-@@ -440,8 +443,8 @@ along with GCC; see the file COPYING3. If not see
- /* The m68k has three kinds of registers, so eight classes would be
- a complete set. One of them is not needed. */
- enum reg_class {
-- NO_REGS, DATA_REGS,
-- ADDR_REGS, FP_REGS,
-+ NO_REGS, DATA_REGS, D0_REGS,
-+ ADDR_REGS, A0_REGS, FP_REGS,
- GENERAL_REGS, DATA_OR_FP_REGS,
- ADDR_OR_FP_REGS, ALL_REGS,
- LIM_REG_CLASSES };
-@@ -449,8 +452,8 @@ enum reg_class {
- #define N_REG_CLASSES (int) LIM_REG_CLASSES
-
- #define REG_CLASS_NAMES \
-- { "NO_REGS", "DATA_REGS", \
-- "ADDR_REGS", "FP_REGS", \
-+ { "NO_REGS", "DATA_REGS", "D0_REGS" \
-+ "ADDR_REGS", "A0_REGS", "FP_REGS", \
- "GENERAL_REGS", "DATA_OR_FP_REGS", \
- "ADDR_OR_FP_REGS", "ALL_REGS" }
-
-@@ -458,7 +461,9 @@ enum reg_class {
- { \
- {0x00000000}, /* NO_REGS */ \
- {0x000000ff}, /* DATA_REGS */ \
-+ {0x00000001}, /* D0_REGS */ \
- {0x0100ff00}, /* ADDR_REGS */ \
-+ {0x00000100}, /* A0_REGS */ \
- {0x00ff0000}, /* FP_REGS */ \
- {0x0100ffff}, /* GENERAL_REGS */ \
- {0x00ff00ff}, /* DATA_OR_FP_REGS */ \
-@@ -614,11 +619,11 @@ __transfer_from_trampoline () \
-
- #define REGNO_OK_FOR_INDEX_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-- || INT_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && INT_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_BASE_P(REGNO) \
- (ADDRESS_REGNO_P (REGNO) \
-- || ADDRESS_REGNO_P (reg_renumber[REGNO]))
-+ || (reg_renumber && ADDRESS_REGNO_P (reg_renumber[REGNO])))
-
- #define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
- (INT_REGNO_P (REGNO) \
-@@ -727,9 +732,49 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- if (cc_prev_status.flags & CC_NO_OVERFLOW) \
- return NO_OV; \
- return NORMAL; } while (0)
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ASCII(MYFILE, MYSTRING, MYLENGTH) \
-+ do { \
-+ FILE *_hide_asm_out_file = (MYFILE); \
-+ const unsigned char *_hide_p = (const unsigned char *) (MYSTRING); \
-+ int _hide_thissize = (MYLENGTH); \
-+ { \
-+ FILE *asm_out_file = _hide_asm_out_file; \
-+ const unsigned char *p = _hide_p; \
-+ int thissize = _hide_thissize; \
-+ int i; \
-+ fprintf (asm_out_file, "\tdc.b \"");
\
-+ \
-+ for (i = 0; i < thissize; i++) \
-+ { \
-+ int c = p[i]; \
-+ if (c == '\"' || c == '\\')
\
-+ putc ('\\', asm_out_file); \
-+ if (ISPRINT (c)) \
-+ putc (c, asm_out_file); \
-+ else \
-+ { \
-+ fprintf (asm_out_file, "\\%o", c);
\
-+ /* After an octal-escape, if a digit follows, \
-+ terminate one string constant and start another. \
-+ The VAX assembler fails to stop reading the escape \
-+ after three digits, so this is the only way we \
-+ can get it to parse the data properly. */ \
-+ if (i < thissize - 1 && ISDIGIT (p[i + 1]))
\
-+ fprintf (asm_out_file, "\"\n\tdc.b \"");
\
-+ } \
-+ } \
-+ fprintf (asm_out_file, "\"\n");
\
-+ } \
-+ } \
-+ while (0)
-+#endif
-
-+
- /* Control the assembler format that we output. */
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_APP_ON "#APP\n"
- #define ASM_APP_OFF "#NO_APP\n"
- #define TEXT_SECTION_ASM_OP "\t.text"
-@@ -739,6 +784,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
- #define LOCAL_LABEL_PREFIX ""
- #define USER_LABEL_PREFIX "_"
- #define IMMEDIATE_PREFIX "#"
-+#else
-+#define ASM_APP_ON ""
-+#define ASM_APP_OFF ""
-+#define TEXT_SECTION_ASM_OP "\tsection .text"
-+#define DATA_SECTION_ASM_OP "\tsection .data"
-+#define GLOBAL_ASM_OP "\txdef\t"
-+#define REGISTER_PREFIX ""
-+#define LOCAL_LABEL_PREFIX "_."
-+#define USER_LABEL_PREFIX "_"
-+#define IMMEDIATE_PREFIX "#"
-+#endif
-
- #define REGISTER_NAMES \
- {REGISTER_PREFIX"d0", REGISTER_PREFIX"d1",
REGISTER_PREFIX"d2", \
-@@ -858,11 +914,17 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- /* The m68k does not use absolute case-vectors, but we must define this macro
- anyway. */
--#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- asm_fprintf (FILE, "\t.long %LL%d\n", VALUE)
--
--#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- asm_fprintf (FILE, "\t.word %LL%d-%LL%d\n", VALUE, REL)
-+#else
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+ asm_fprintf (FILE, "\tdc.l %LL%d\n", VALUE)
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+ asm_fprintf (FILE, "\tdc.w %LL%d-%LL%d\n", VALUE, REL)
-+#endif
-
- /* We don't have a way to align to more than a two-byte boundary, so do the
- best we can and don't complain. */
-@@ -872,13 +934,24 @@ do { if (cc_prev_status.flags & CC_IN_68881) \
-
- #ifdef HAVE_GAS_BALIGN_AND_P2ALIGN
- /* Use "move.l %a4,%a4" to advance within code. */
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
- if ((LOG) > 0) \
- fprintf ((FILE), "\t.balignw %u,0x284c\n", 1 << (LOG));
- #endif
-+#else
-+#define ASM_OUTPUT_ALIGN_WITH_NOP(FILE,LOG) \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "\tcnop 0,%u\n", 1 << (LOG));
-+#endif
-
-+#ifndef TARGET_AMIGAOS_VASM
- #define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.skip %u\n", (int)(SIZE))
-+#else
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+ fprintf (FILE, "\tds.b %u\n", (int)(SIZE))
-+#endif
-
- #define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
- ( fputs (".comm ", (FILE)), \
-@@ -971,3 +1044,8 @@ extern int m68k_sched_address_bypass_p (rtx_insn *, rtx_insn *);
- extern int m68k_sched_indexed_address_bypass_p (rtx_insn *, rtx_insn *);
-
- #define CPU_UNITS_QUERY 1
-+
-+#if 1
-+extern void default_stabs_asm_out_constructor (rtx, int);
-+extern void default_stabs_asm_out_destructor (rtx, int);
-+#endif
-diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
-index ec37bd76f55f..05ef02027f01 100644
---- gcc/config/m68k/m68k.md
-+++ gcc/config/m68k/m68k.md
-@@ -128,13 +128,11 @@
- (UNSPECV_TAS_2 4)
- ])
-
--;; Registers by name.
-+;; Registers by name. SBF: Do not define PIC_REG / A6_REG here!
- (define_constants
- [(D0_REG 0)
- (A0_REG 8)
- (A1_REG 9)
-- (PIC_REG 13)
-- (A6_REG 14)
- (SP_REG 15)
- (FP0_REG 16)
- ])
-@@ -1566,7 +1564,7 @@
- ;; so we will prefer it to them.
-
- (define_insn "pushasi"
-- [(set (match_operand:SI 0 "push_operand" "=m")
-+ [(set (match_operand:SI 0 "push_operand" "=<")
- (match_operand:SI 1 "address_operand" "p"))]
- ""
- "pea %a1"
-@@ -7204,6 +7202,7 @@
- "operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);")
-
- ;; Changing pea X.w into a move.l is no real win here.
-+;; SBF: also disable converting pea for baserel insns!
- (define_peephole2
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
- (match_operand:SI 0 "const_int_operand" "")))
-@@ -7213,7 +7212,8 @@
- && !reg_mentioned_p (stack_pointer_rtx, operands[2])
- && !(CONST_INT_P (operands[2]) && INTVAL (operands[2]) != 0
- && IN_RANGE (INTVAL (operands[2]), -0x8000, 0x7fff)
-- && !valid_mov3q_const (INTVAL (operands[2])))"
-+ && !valid_mov3q_const (INTVAL (operands[2])))
-+ && !amiga_is_const_pic_ref(operands[2])"
- [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 0)))
- (set (match_dup 1) (match_dup 2))]
- {
-diff --git a/gcc/config/m68k/m68kamigaos.h b/gcc/config/m68k/m68kamigaos.h
-new file mode 100644
-index 000000000000..3f3aafc5f254
---- /dev/null
-+++ gcc/config/m68k/m68kamigaos.h
-@@ -0,0 +1,760 @@
-+/* m68kelf support, derived from m68kv4.h */
-+
-+/* Target definitions for GNU compiler for mc680x0 running AmigaOs
-+ Copyright (C) 1991-2016 Free Software Foundation, Inc.
-+
-+ Written by Ron Guilmette (rfg(a)netcom.com) and Fred Fish (fnf(a)cygnus.com).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 3, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING3. If not see
-+<http://www.gnu.org/licenses/>. */
-+
-+#ifndef TARGET_AMIGA
-+#define TARGET_AMIGA 1
-+#endif
-+
-+#define HAS_INIT_SECTION
-+
-+#ifndef SWBEG_ASM_OP
-+#define SWBEG_ASM_OP "\t.swbeg\t"
-+#endif
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#undef ASM_STABS_OP
-+#define ASM_STABS_OP "|\t.stabs\t"
-+
-+#undef ASM_STABD_OP
-+#define ASM_STABD_OP "|\t.stabd\t"
-+
-+#undef ASM_STABN_OP
-+#define ASM_STABN_OP "|\t.stabn\t"
-+#endif
-+
-+#undef PIC_REG
-+#define PIC_REG 12
-+
-+#undef FRAME_POINTER_REGNUM
-+#define FRAME_POINTER_REGNUM 13
-+
-+#undef M68K_REGNAME
-+#define M68K_REGNAME(r) ( \
-+ ( ((r) == FRAME_POINTER_REGNUM) \
-+ && frame_pointer_needed) ? \
-+ M68K_FP_REG_NAME : reg_names[(r)])
-+
-+
-+
-+/* Here are three prefixes that are used by asm_fprintf to
-+ facilitate customization for alternate assembler syntaxes.
-+ Machines with no likelihood of an alternate syntax need not
-+ define these and need not use asm_fprintf. */
-+
-+/* The prefix for register names. Note that REGISTER_NAMES
-+ is supposed to include this prefix. Also note that this is NOT an
-+ fprintf format string, it is a literal string */
-+
-+#undef REGISTER_PREFIX
-+#define REGISTER_PREFIX ""
-+
-+/* The prefix for local (compiler generated) labels.
-+ These labels will not appear in the symbol table. */
-+
-+#undef LOCAL_LABEL_PREFIX
-+#ifndef TARGET_AMIGAOS_VASM
-+#define LOCAL_LABEL_PREFIX "."
-+#else
-+#define LOCAL_LABEL_PREFIX "_."
-+#endif
-+
-+/* The prefix to add to user-visible assembler symbols. */
-+
-+#undef USER_LABEL_PREFIX
-+#define USER_LABEL_PREFIX "_"
-+
-+/* config/m68k.md has an explicit reference to the program counter,
-+ prefix this by the register prefix. */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp %%pc@(2,%0:w)"; \
-+ } while (0)
-+#else
-+#define ASM_RETURN_CASE_JUMP \
-+ do { \
-+ return "jmp (2,pc,%0.w)"; \
-+ } while (0)
-+#endif
-+
-+/* This is how to output an assembler line that says to advance the
-+ location counter to a multiple of 2**LOG bytes. */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#ifndef ALIGN_ASM_OP
-+#define ALIGN_ASM_OP "\t.align\t"
-+#endif
-+#else
-+#define ALIGN_ASM_OP "\talign\t"
-+#endif
-+
-+#undef ASM_OUTPUT_ALIGN
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, 1 << (LOG)); \
-+} while (0)
-+#else
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+do { \
-+ if ((LOG) > 0) \
-+ fprintf ((FILE), "%s%u\n", ALIGN_ASM_OP, (LOG)); \
-+} while (0)
-+#endif
-+
-+#if 0
-+extern int amiga_declare_object;
-+
-+#define ASM_DECLARE_OBJECT_NAME(FILE,NAME,DECL) \
-+if (!DECL_INITIAL (DECL) || \
-+ initializer_zerop (DECL_INITIAL (decl))) \
-+ { \
-+ amiga_declare_object = 1; \
-+ fprintf ((FILE), ".comm\t%s,", NAME); \
-+ } \
-+else \
-+ASM_OUTPUT_LABEL (FILE, NAME)
-+
-+#undef ASM_OUTPUT_SKIP
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+if (amiga_declare_object) \
-+ fprintf (FILE, "%u\n", (int)(SIZE)); \
-+else \
-+ fprintf (FILE, "\t.skip %u\n", (int)(SIZE)); \
-+amiga_declare_object = 0
-+#endif
-+
-+/* Register in which address to store a structure value is passed to a
-+ function. The default in m68k.h is a1. For m68k/SVR4 it is a0. */
-+
-+#undef M68K_STRUCT_VALUE_REGNUM
-+#define M68K_STRUCT_VALUE_REGNUM A0_REG
-+
-+/* The static chain regnum defaults to a0, but we use that for
-+ structure return, so have to use a1 for the static chain. */
-+
-+#undef STATIC_CHAIN_REGNUM
-+#define STATIC_CHAIN_REGNUM A1_REG
-+#undef M68K_STATIC_CHAIN_REG_NAME
-+#define M68K_STATIC_CHAIN_REG_NAME REGISTER_PREFIX "a1"
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_COMMENT_START "|"
-+#else
-+#define ASM_COMMENT_START "|"
-+#endif
-+
-+/* Define how the m68k registers should be numbered for Dwarf output.
-+ The numbering provided here should be compatible with the native
-+ SVR4 SDB debugger in the m68k/SVR4 reference port, where d0-d7
-+ are 0-7, a0-a8 are 8-15, and fp0-fp7 are 16-23. */
-+
-+#undef DBX_REGISTER_NUMBER
-+#define DBX_REGISTER_NUMBER(REGNO) (REGNO)
-+
-+#if 0
-+/* SVR4 m68k assembler is bitching on the `comm i,1,1' which askes for
-+ 1 byte alignment. Don't generate alignment for COMMON seems to be
-+ safer until we the assembler is fixed. */
-+#undef ASM_OUTPUT_ALIGNED_COMMON
-+/* Same problem with this one. */
-+#undef ASM_OUTPUT_ALIGNED_LOCAL
-+#endif
-+
-+#undef ASM_OUTPUT_COMMON
-+#undef ASM_OUTPUT_LOCAL
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".comm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+ ( switch_to_section (bss_section), \
-+ fputs ("|.comm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)), \
-+ fputs ("\txdef ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), "\n"))
-+#endif
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( fputs (".lcomm ", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ",%u\n", (int)(SIZE)))
-+#else
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+( switch_to_section (bss_section), \
-+ fputs ("|.lcomm\n\tcnop 0,4\n", (FILE)), \
-+ assemble_name ((FILE), (NAME)), \
-+ fprintf ((FILE), ":\n\tds.b %u\n", (int)(SIZE)))
-+#endif
-+
-+/* Currently, JUMP_TABLES_IN_TEXT_SECTION must be defined in order to
-+ keep switch tables in the text section. */
-+
-+#define JUMP_TABLES_IN_TEXT_SECTION 1
-+
-+/* In m68k svr4, using swbeg is the standard way to do switch
-+ table. */
-+#undef ASM_OUTPUT_BEFORE_CASE_LABEL
-+#define ASM_OUTPUT_BEFORE_CASE_LABEL(FILE,PREFIX,NUM,TABLE) \
-+ fprintf ((FILE), "%s&%d\n", SWBEG_ASM_OP, XVECLEN (PATTERN (TABLE),
1));
-+/* end of stuff from m68kv4.h */
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#undef BSS_SECTION_ASM_OP
-+#define BSS_SECTION_ASM_OP "\t.bss"
-+#else
-+#define BSS_SECTION_ASM_OP "\tsection\tbss"
-+#endif
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#undef DATA_SECTION_ASM_OP
-+#define DATA_SECTION_ASM_OP "\t.data"
-+#else
-+#define DATA_SECTION_ASM_OP "\tsection\tdata"
-+#endif
-+
-+#ifndef ASM_OUTPUT_ALIGNED_BSS
-+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
-+ asm_output_aligned_bss (FILE, DECL, NAME, SIZE, ALIGN)
-+#endif
-+
-+
-+/* Specs, switches. */
-+
-+/* amiga/amigaos are the new "standard" defines for the Amiga.
-+ MCH_AMIGA, AMIGA, __chip etc. are used in other compilers and are
-+ provided for compatibility reasons.
-+ When creating shared libraries, use different 'errno'. */
-+
-+#undef TARGET_OS_CPP_BUILTINS
-+#define TARGET_OS_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define ("__chip=__attribute__((__chip__))"); \
-+ builtin_define ("__fast=__attribute__((__fast__))"); \
-+ builtin_define ("__far=__attribute__((__far__))"); \
-+ builtin_define ("__saveds=__attribute__((__saveds__))"); \
-+ builtin_define ("__interrupt=__attribute__((__interrupt__))"); \
-+ builtin_define ("__stackext=__attribute__((__stackext__))"); \
-+ builtin_define ("__regargs=__attribute__((__regparm__(2)))"); \
-+ builtin_define ("__stdargs=__attribute__((__stkparm__))"); \
-+ builtin_define ("__aligned=__attribute__((__aligned__(4)))"); \
-+ builtin_define_std ("amiga"); \
-+ builtin_define_std ("amigaos"); \
-+ builtin_define_std ("AMIGA"); \
-+ builtin_define_std ("MCH_AMIGA"); \
-+ builtin_assert ("system=amigaos"); \
-+ } \
-+ while (0)
-+
-+#if 0
-+if (target_flags & (MASK_RESTORE_A4|MASK_ALWAYS_RESTORE_A4)) \
-+ builtin_define ("errno=(*ixemul_errno)"); \
-+
-+#endif
-+
-+/* put return values in FPU build in FP0 Reg */
-+#undef FUNCTION_VALUE_REGNO_P
-+#define FUNCTION_VALUE_REGNO_P(N) \
-+ ((N) == D0_REG || (TARGET_68881 && (N) == FP0_REG))
-+
-+// see 930623-1.c
-+// ((N) == D0_REG || (N) == A0_REG || (TARGET_68881 && (N) == FP0_REG))
-+
-+/* Inform the program which CPU we compile for. */
-+
-+//#undef TARGET_CPU_CPP_BUILTINS
-+/*
-+ use --with-cpu=mc68040 etc.. instead on config. code was after #define
TARGET_CPU_CPP_BUILTINS()
-+ if (TARGET_68040_ONLY) \
-+ { \
-+ if (TARGET_68060) \
-+ builtin_define_std ("mc68060"); \
-+ else \
-+ builtin_define_std ("mc68040"); \
-+ } \
-+ else if (TARGET_68030 && !TARGET_68040) \
-+ builtin_define_std ("mc68030"); \
-+ else if (TARGET_68020) \
-+ builtin_define_std ("mc68020"); \
-+ builtin_define_std ("mc68000"); \
-+*/
-+/*
-+#define TARGET_CPU_CPP_BUILTINS() \
-+ do \
-+ { \
-+ builtin_define_std ("mc68040"); \
-+ if (flag_pic > 2) \
-+ { \
-+ builtin_define ("__pic__"); \
-+ if (flag_pic > 3) \
-+ builtin_define ("__PIC__"); \
-+ } \
-+ builtin_assert ("cpu=m68k"); \
-+ builtin_assert ("machine=m68k"); \
-+ } \
-+ while (0)
-+*/
-+
-+/* When creating shared libraries, use different 'errno'. */
-+#define CPP_IXEMUL_SPEC \
-+ "%{!ansi:-Dixemul} -D__ixemul__ -D__ixemul " \
-+ "%{malways-restore-a4:-Derrno=(*ixemul_errno)} " \
-+ "%{mrestore-a4:-Derrno=(*ixemul_errno)}"
-+#define CPP_LIBNIX_SPEC \
-+ "-isystem %:sdk_root(libnix/include) " \
-+ "%{!ansi:-Dlibnix} -D__libnix__ -D__libnix"
-+#define CPP_CLIB2_SPEC \
-+ "-isystem %:sdk_root(clib2/include) " \
-+ "%{!ansi:-DCLIB2} -D__CLIB2__ -D__CLIB2"
-+
-+/* Define __HAVE_68881__ in preprocessor according to the -m flags.
-+ This will control the use of inline 68881 insns in certain macros.
-+ Note: it should be set in TARGET_CPU_CPP_BUILTINS but TARGET_68881
-+ isn't the same -m68881 since its also true for -m680[46]0 ...
-+ Differentiate between libnix and ixemul. */
-+
-+#define CPP_SPEC \
-+ "%{m68881:-D__HAVE_68881__} " \
-+ "%{!ansi:" \
-+ "%{m68020:-Dmc68020} " \
-+ "%{mc68020:-Dmc68020} " \
-+ "%{m68020-40:-Dmc68020} " \
-+ "%{m68020-60:-Dmc68020} " \
-+ "%{m68030:-Dmc68030} " \
-+ "%{m68040:-Dmc68040} " \
-+ "%{m68060:-Dmc68060}} " \
-+ "%{m68020:-D__mc68020__ -D__mc68020} " \
-+ "%{mc68020:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-40:-D__mc68020__ -D__mc68020} " \
-+ "%{m68020-60:-D__mc68020__ -D__mc68020} " \
-+ "%{m68030:-D__mc68030__ -D__mc68030} " \
-+ "%{m68040:-D__mc68040__ -D__mc68040} " \
-+ "%{m68060:-D__mc68060__ -D__mc68060} " \
-+ "%{noixemul:%(cpp_libnix)} " \
-+ "%{mcrt=nix*:%(cpp_libnix)} " \
-+ "%{mcrt=ixemul:%(cpp_ixemul)} " \
-+ "%{mcrt=clib2:%(cpp_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(cpp_clib2)}}"
-+
-+/* Various -m flags require special flags to the assembler. */
-+
-+#undef ASM_SPEC
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_SPEC \
-+ "%(asm_cpu) %(asm_cpu_default) %{msmall-code:-sc} %{!msmall-code:-S}"
-+#else
-+#define ASM_SPEC \
-+ "-gas -esc -ldots -Fhunk -quiet %(asm_cpu) %(asm_cpu_default)
%{msmall-code:-sc}"
-+#endif
-+
-+#undef ASM_CPU_SPEC
-+#define ASM_CPU_SPEC \
-+ "%{mcpu=*:-m%*} " \
-+ "%{m68000|mc68000:-m68010} " \
-+ "%{m6802*|mc68020:-m68020} " \
-+ "%{m68030} " \
-+ "%{m68040} " \
-+ "%{m68060}"
-+
-+#ifndef TARGET_AMIGAOS_VASM
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:%{!mcpu=*:-m68000}}}"
-+#else
-+#define ASM_CPU_DEFAULT_SPEC \
-+ "%{!m680*:%{!mc680*:-m68000}}"
-+#endif
-+
-+/* Choose the right startup file, depending on whether we use base relative
-+ code, base relative code with automatic relocation (-resident), their
-+ 32-bit versions, libnix, profiling or plain crt0.o. */
-+
-+#define STARTFILE_IXEMUL_SPEC \
-+ "%{fbaserel:%{!resident:bcrt0.o%s}}" \
-+ "%{resident:rcrt0.o%s}" \
-+ "%{fbaserel32:%{!resident32:lcrt0.o%s}}" \
-+ "%{resident32:scrt0.o%s}" \
-+ "%{!resident:%{!fbaserel:%{!resident32:%{!fbaserel32:" \
-+ "%{pg:gcrt0.o%s}%{!pg:%{p:mcrt0.o%s}%{!p:crt0.o%s}}}}}}"
-+#define STARTFILE_LIBNIX_SPEC \
-+ "%:sdk_root(libnix/lib/libnix/ " \
-+ "%{ramiga-*:" \
-+ "%{ramiga-lib:libinit.o%s}" \
-+ "%{ramiga-libr:libinitr.o%s}" \
-+ "%{ramiga-dev:devinit.o%s}}" \
-+ "%{!ramiga-*:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:" \
-+ "%{fbaserel32:nlbcrt0.o%s}" \
-+ "%{!fbaserel32:ncrt0.o%s}}}}" \
-+ ")"
-+
-+#define STARTFILE_CLIB2_SPEC \
-+ "%:sdk_root(clib2/lib/ " \
-+ "%{resident32:nr32crt0.o%s}" \
-+ "%{!resident32:" \
-+ "%{fbaserel32:nb32crt0.o%s}" \
-+ "%{!fbaserel32:" \
-+ "%{resident:nrcrt0.o%s}" \
-+ "%{!resident:" \
-+ "%{fbaserel:nbcrt0.o%s}" \
-+ "%{!fbaserel:ncrt0.o%s}}}}" \
-+ ")"
-+
-+#undef STARTFILE_SPEC
-+#ifdef TARGET_AMIGAOS_VASM
-+#define STARTFILE_SPEC \
-+ "startup%O%s"
-+#else
-+#define STARTFILE_SPEC \
-+ "%{noixemul:%(startfile_libnix)} " \
-+ "%{mcrt=nix*:%(startfile_libnix)} " \
-+ "%{mcrt=ixemul:%(startfile_ixemul)} " \
-+ "%{mcrt=clib2:%(startfile_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(startfile_clib2)}}"
-+#endif
-+
-+#define ENDFILE_IXEMUL_SPEC ""
-+#define ENDFILE_LIBNIX_SPEC "-lstubs"
-+#define ENDFILE_CLIB2_SPEC ""
-+
-+#undef ENDFILE_SPEC
-+#define ENDFILE_SPEC \
-+ "%{noixemul:%(endfile_libnix)} " \
-+ "%{mcrt=nix*:%(endfile_libnix)} " \
-+ "%{mcrt=ixemul:%(endfile_ixemul)} " \
-+ "%{mcrt=clib2:%(endfile_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(endfile_clib2)}}"
-+
-+
-+/* Automatically search libamiga.a for AmigaOS specific functions. Note
-+ that we first search the standard C library to resolve as much as
-+ possible from there, since it has names that are duplicated in libamiga.a
-+ which we *don't* want from there. Then search libamiga.a for any calls
-+ that were not generated inline, and finally search the standard C library
-+ again to resolve any references that libamiga.a might have generated.
-+ This may only be a temporary solution since it might be better to simply
-+ remove the things from libamiga.a that should be pulled in from libc.a
-+ instead, which would eliminate the first reference to libc.a. Note that
-+ if we don't search it automatically, it is very easy for the user to try
-+ to put in a -lamiga himself and get it in the wrong place, so that (for
-+ example) calls like sprintf come from -lamiga rather than -lc. */
-+
-+#define LIB_IXEMUL_SPEC \
-+ "%{!p:%{!pg:-lc -lamiga -lc}} " \
-+ "%{p:-lc_p} %{pg:-lc_p}"
-+#define LIB_LIBNIX_SPEC \
-+ "-lnixmain -lnix " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20} " \
-+ "-lamiga " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
-+#define LIB_CLIB2_SPEC \
-+ "-lc -lamiga -ldebug " \
-+ "%{mstackcheck:-lstack} " \
-+ "%{mstackextend:-lstack}"
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LIB_SPEC \
-+ "-lvc -lamiga "
-+#else
-+#define LIB_SPEC \
-+ "%{noixemul:%(lib_libnix)} " \
-+ "%{mcrt=nix*:%(lib_libnix)} " \
-+ "%{mcrt=ixemul:%(lib_ixemul)} " \
-+ "%{mcrt=clib2:%(lib_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(lib_clib2)}}"
-+#endif
-+
-+#define LIBGCC_IXEMUL_SPEC ""
-+#define LIBGCC_LIBNIX_SPEC "-lnix -fl libnix " \
-+ "%{mcrt=*:-l%*} " \
-+ "%{!mcrt=*:-lnix20} -lstubs"
-+#define LIBGCC_CLIB2_SPEC "-lc"
-+#define LIBGCC_SPEC "-lgcc " \
-+ "%{noixemul:%(libgcc_libnix)} " \
-+ "%{mcrt=nix*:%(libgcc_libnix)} " \
-+ "%{mcrt=ixemul:%(libgcc_ixemul)} " \
-+ "%{mcrt=clib2:%(libgcc_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(libgcc_clib2)}}"
-+
-+
-+/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-+ compatible debug hunk.
-+ Also, pass appropriate linker flavours depending on user-supplied
-+ commandline options. */
-+
-+#define LINK_IXEMUL_SPEC ""
-+#define LINK_LIBNIX_SPEC "-L%:sdk_root(libnix/lib) -fl libnix"
-+#define LINK_CLIB2_SPEC "-L%:sdk_root(clib2/lib)"
-+
-+/* If debugging, tell the linker to output amiga-hunk symbols *and* a BSD
-+ compatible debug hunk.
-+ Also, pass appropriate linker flavours depending on user-supplied
-+ commandline options. */
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LINK_SPEC \
-+ "%{noixemul:%(link_libnix)} " \
-+ "%{mcrt=nix*:%(link_libnix)} " \
-+ "%{mcrt=ixemul:%(link_ixemul)} " \
-+ "%{mcrt=clib2:%(link_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(link_clib2)}} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl
libnix} %{mcrt=nix*:-fl libnix}} " \
-+ "%{mcpu=68020:-fl libm020} " \
-+ "%{m68020:-fl libm020} " \
-+ "%{mc68020:-fl libm020} " \
-+ "%{m68030:-fl libm020} " \
-+ "%{m68040:-fl libm020} " \
-+ "%{m68060:-fl libm020} " \
-+ "%{m68020-40:-fl libm020} " \
-+ "%{m68020-60:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+#else
-+#define LINK_SPEC \
-+ "%{noixemul:%(link_libnix)} " \
-+ "%{mcrt=nix*:%(link_libnix)} " \
-+ "%{mcrt=ixemul:%(link_ixemul)} " \
-+ "%{mcrt=clib2:%(link_clib2)} " \
-+ "%{!noixemul:%{!mcrt*:%(link_clib2)}} " \
-+ "%{fbaserel:%{!resident:-m amiga_bss -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident:-m amiga_bss -amiga-datadata-reloc -fl libb %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}} " \
-+ "%{fbaserel32:%{!resident32:-m amiga_bss -fl libb32 %{noixemul:-fl libnix}
%{mcrt=nix*:-fl libnix}}} " \
-+ "%{resident32:-m amiga_bss -amiga-datadata-reloc -fl libb32 %{noixemul:-fl
libnix} %{mcrt=nix*:-fl libnix}} " \
-+ "%{g:-amiga-debug-hunk} " \
-+ "%{mcpu=68020:-fl libm020} " \
-+ "%{mcpu=68030:-fl libm020} " \
-+ "%{mcpu=68040:-fl libm020} " \
-+ "%{mcpu=68060:-fl libm020} " \
-+ "%{m68020:-fl libm020} " \
-+ "%{mc68020:-fl libm020} " \
-+ "%{m68030:-fl libm020} " \
-+ "%{m68040:-fl libm020} " \
-+ "%{m68060:-fl libm020} " \
-+ "%{m68020-40:-fl libm020} " \
-+ "%{m68020-60:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+#endif
-+
-+/* Translate '-resident' to '-fbaserel' (they differ in linking stage
only).
-+ Don't put function addresses in registers for PC-relative code. */
-+
-+#define CC1_SPEC \
-+ "%{resident:-fbaserel} " \
-+ "%{resident32:-fbaserel32} " \
-+ "%{msmall-code:-fno-function-cse}"
-+
-+#define LINK_CPU_SPEC \
-+ "%{m6802*|mc68020|m68030|m68040|m68060:-fl libm020} " \
-+ "%{m68881:-fl libm881}"
-+
-+/* [cahirwpz] A modified copy of LINK_COMMAND_SPEC from gcc/gcc.c file.
-+ Don't prepend libgcc.a to link libraries and make sure the options is
-+ at the end of command line. Otherwise linker chooses generic functions
-+ from libgcc.a instead AmigaOS-specific counterparts from libnix.a. */
-+
-+#ifdef TARGET_AMIGAOS_VASM
-+#define LINK_COMMAND_SPEC \
-+ "%{!fsyntax-only:" \
-+ "%{!c:" \
-+ "%{!M:" \
-+ "%{!MM:" \
-+ "%{!E:" \
-+ "%{!S:" \
-+ "%(linker) -Cvbcc %l %X %{o*} %{A} %{d} %{e*} %{m} " \
-+ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
-+ "%{static:} %{L*} %D %o " \
-+ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
-+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-+ "%{T*} }}}}}} "
-+#else
-+#define LINK_COMMAND_SPEC \
-+ "%{!fsyntax-only:" \
-+ "%{!c:" \
-+ "%{!M:" \
-+ "%{!MM:" \
-+ "%{!E:" \
-+ "%{!S:" \
-+ "%(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} " \
-+ "%{N} %{n} %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%S}}} " \
-+ "%{static:} %{L*} %D %o " \
-+ "%{!nostdlib:%{!nodefaultlibs:%L}} " \
-+ "%{!A:%{!nostdlib:%{!nostartfiles:%E}}} " \
-+ "%{!nostdlib:%{!nodefaultlibs:%G}} " \
-+ "%{T*} }}}}}} "
-+#endif
-+
-+extern const char * amiga_m68k_prefix_func(int, const char **);
-+
-+#define EXTRA_SPEC_FUNCTIONS \
-+ { "sdk_root", amiga_m68k_prefix_func },
-+
-+/* This macro defines names of additional specifications to put in the specs
-+ that can be used in various specifications like CC1_SPEC. Its definition
-+ is an initializer with a subgrouping for each command option.
-+
-+ Each subgrouping contains a string constant, that defines the
-+ specification name, and a string constant that used by the GCC driver
-+ program.
-+
-+ Do not define this macro if it does not need to do anything. */
-+#undef EXTRA_SPECS
-+#define EXTRA_SPECS \
-+ {"asm_cpu", ASM_CPU_SPEC }, \
-+ {"asm_cpu_default", ASM_CPU_DEFAULT_SPEC }, \
-+ {"link_cpu", LINK_CPU_SPEC }, \
-+ {"cpp_ixemul", CPP_IXEMUL_SPEC}, \
-+ {"cpp_libnix", CPP_LIBNIX_SPEC}, \
-+ {"cpp_clib2", CPP_CLIB2_SPEC}, \
-+ {"lib_ixemul", LIB_IXEMUL_SPEC}, \
-+ {"lib_libnix", LIB_LIBNIX_SPEC}, \
-+ {"lib_clib2", LIB_CLIB2_SPEC}, \
-+ {"link_ixemul", LINK_IXEMUL_SPEC}, \
-+ {"link_libnix", LINK_LIBNIX_SPEC}, \
-+ {"link_clib2", LINK_CLIB2_SPEC}, \
-+ {"startfile_ixemul", STARTFILE_IXEMUL_SPEC}, \
-+ {"startfile_libnix", STARTFILE_LIBNIX_SPEC}, \
-+ {"startfile_clib2", STARTFILE_CLIB2_SPEC}, \
-+ {"endfile_ixemul", ENDFILE_IXEMUL_SPEC}, \
-+ {"endfile_libnix", ENDFILE_LIBNIX_SPEC}, \
-+ {"endfile_clib2", ENDFILE_CLIB2_SPEC}, \
-+ {"libgcc_ixemul", LIBGCC_IXEMUL_SPEC}, \
-+ {"libgcc_libnix", LIBGCC_LIBNIX_SPEC}, \
-+ {"libgcc_clib2", LIBGCC_CLIB2_SPEC}
-+
-+/* begin-GG-local: dynamic libraries */
-+
-+extern int amigaos_do_collecting (void);
-+extern void amigaos_gccopts_hook (const char *);
-+extern void amigaos_libname_hook (const char* arg);
-+extern void amigaos_collect2_cleanup (void);
-+extern void amigaos_prelink_hook (const char **, int *);
-+extern void amigaos_postlink_hook (const char *);
-+
-+/* This macro is used to check if all collect2 facilities should be used.
-+ We need a few special ones, like stripping after linking. */
-+
-+#define DO_COLLECTING (do_collecting || amigaos_do_collecting())
-+
-+/* This macro is called in collect2 for every GCC argument name.
-+ ARG is a part of commandline (without '\0' at the end). */
-+
-+#define COLLECT2_GCC_OPTIONS_HOOK(ARG) amigaos_gccopts_hook(ARG)
-+
-+/* This macro is called in collect2 for every ld's "-l" or "*.o"
or "*.a"
-+ argument. ARG is a complete argument, with '\0' at the end. */
-+
-+#define COLLECT2_LIBNAME_HOOK(ARG) amigaos_libname_hook(ARG)
-+
-+/* This macro is called at collect2 exit, to clean everything up. */
-+
-+#define COLLECT2_EXTRA_CLEANUP amigaos_collect2_cleanup
-+
-+/* This macro is called just before the first linker invocation.
-+ LD1_ARGV is "char** argv", which will be passed to "ld". STRIP
is an
-+ *address* of "strip_flag" variable. */
-+
-+#define COLLECT2_PRELINK_HOOK(LD1_ARGV, STRIP) \
-+amigaos_prelink_hook((const char **)(LD1_ARGV), (STRIP))
-+
-+/* This macro is called just after the first linker invocation, in place of
-+ "nm" and "ldd". OUTPUT_FILE is the executable's filename.
*/
-+
-+#define COLLECT2_POSTLINK_HOOK(OUTPUT_FILE) amigaos_postlink_hook(OUTPUT_FILE)
-+/* end-GG-local */
-+
-+#undef MAX_OFILE_ALIGNMENT
-+#define MAX_OFILE_ALIGNMENT ((1 << 15)*BITS_PER_UNIT)
-+
-+#undef FIXED_INCLUDE_DIR
-+#define FIXED_INCLUDE_DIR CROSS_INCLUDE_DIR "/../../include"
-+
-+// this disables tree_loop_distribute_patterns
-+#define C_COMMON_OVERRIDE_OPTIONS flag_no_builtin = 1
-+/* Baserel support. */
-+
-+extern int amiga_is_const_pic_ref(const_rtx x);
-+
-+#undef CONSTANT_ADDRESS_P
-+#define CONSTANT_ADDRESS_P(X) \
-+((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
-+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
-+ || GET_CODE (X) == HIGH \
-+ ))
-+
-+
-+
-+/* Given that symbolic_operand(X), return TRUE if no special
-+ base relative relocation is necessary */
-+
-+#undef LEGITIMATE_PIC_OPERAND_P
-+#define LEGITIMATE_PIC_OPERAND_P(X) ( \
-+ ! symbolic_operand (X, VOIDmode) && \
-+ ! amiga_is_const_pic_ref(X))
-+
-+// (GET_CODE(X) == CONST && (GET_CODE(XEXP(X, 0)) == SYMBOL_REF ||
GET_CODE(XEXP(X, 0)) == LABEL_REF) && !CONSTANT_POOL_ADDRESS_P (XEXP(X, 0))) ||
-+
-+#undef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".text"
-+
-+#undef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".text"
-+
-+#define EH_TABLES_CAN_BE_READ_ONLY 1
-+
-+
-+/* Max. number of data, address and float registers to be used for passing
-+ integer, pointer and float arguments when TARGET_REGPARM.
-+ It's 4, so d0-d3, a0-a3 and fp0-fp3 can be used. */
-+#undef AMIGAOS_MAX_REGPARM
-+#define AMIGAOS_MAX_REGPARM 4
-+
-+/* The default number of data, address and float registers to use when
-+ user specified '-mregparm' switch, not '-mregparm=<value>'
option. */
-+#undef AMIGAOS_DEFAULT_REGPARM
-+#define AMIGAOS_DEFAULT_REGPARM 2
-+
-+/* 1 if N is a possible register number for function argument passing. */
-+#undef FUNCTION_ARG_REGNO_P
-+#define FUNCTION_ARG_REGNO_P(N) amigaos_function_arg_reg(N)
-+
-+extern int
-+amigaos_function_arg_reg(unsigned regno);
-+
-+//extern bool debug_recog(char const * txt, int which_alternative, int n, rtx *
operands);
-diff --git a/gcc/config/m68k/m68kemb.h b/gcc/config/m68k/m68kemb.h
-index 0d8d88c74ea9..29b3e194f12d 100644
---- gcc/config/m68k/m68kemb.h
-+++ gcc/config/m68k/m68kemb.h
-@@ -32,12 +32,14 @@
- #define NEEDS_UNTYPED_CALL 1
-
- /* Target OS builtins. */
-+#ifndef TARGET_OS_CPP_BUILTINS
- #define TARGET_OS_CPP_BUILTINS() \
- do \
- { \
- builtin_define ("__embedded__"); \
- } \
- while (0)
-+#endif
-
- /* Override the default LIB_SPEC from gcc.c. We don't currently support
- profiling, or libg.a. */
-diff --git a/gcc/config/m68k/math-68881.h b/gcc/config/m68k/math-68881.h
-index 6d9f8b2d4a1f..20a5037cc525 100644
---- gcc/config/m68k/math-68881.h
-+++ gcc/config/m68k/math-68881.h
-@@ -37,7 +37,7 @@
- September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
-
- /* Changed by Ian Lance Taylor:
-- September 1994, use extern inline instead of static inline. */
-+ September 1994, use inline instead of static inline. */
-
- #ifndef __math_68881
- #define __math_68881
-@@ -64,7 +64,7 @@
- })
- #endif
-
--__inline extern double
-+__inline double
- sin (double x)
- {
- double value;
-@@ -75,7 +75,7 @@ sin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cos (double x)
- {
- double value;
-@@ -86,7 +86,7 @@ cos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tan (double x)
- {
- double value;
-@@ -97,7 +97,7 @@ tan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- asin (double x)
- {
- double value;
-@@ -108,7 +108,7 @@ asin (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- acos (double x)
- {
- double value;
-@@ -119,7 +119,7 @@ acos (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan (double x)
- {
- double value;
-@@ -130,7 +130,7 @@ atan (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atan2 (double y, double x)
- {
- double pi, pi_over_2;
-@@ -187,7 +187,7 @@ atan2 (double y, double x)
- }
- }
-
--__inline extern double
-+__inline double
- sinh (double x)
- {
- double value;
-@@ -198,7 +198,7 @@ sinh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- cosh (double x)
- {
- double value;
-@@ -209,7 +209,7 @@ cosh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- tanh (double x)
- {
- double value;
-@@ -220,7 +220,7 @@ tanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- atanh (double x)
- {
- double value;
-@@ -231,7 +231,7 @@ atanh (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- exp (double x)
- {
- double value;
-@@ -242,7 +242,7 @@ exp (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- expm1 (double x)
- {
- double value;
-@@ -253,7 +253,7 @@ expm1 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log (double x)
- {
- double value;
-@@ -264,7 +264,7 @@ log (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log1p (double x)
- {
- double value;
-@@ -275,7 +275,7 @@ log1p (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- log10 (double x)
- {
- double value;
-@@ -286,7 +286,7 @@ log10 (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- sqrt (double x)
- {
- double value;
-@@ -297,13 +297,13 @@ sqrt (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- hypot (double x, double y)
- {
- return sqrt (x*x + y*y);
- }
-
--__inline extern double
-+__inline double
- pow (double x, double y)
- {
- if (x > 0)
-@@ -352,7 +352,7 @@ pow (double x, double y)
- }
- }
-
--__inline extern double
-+__inline double
- fabs (double x)
- {
- double value;
-@@ -363,7 +363,7 @@ fabs (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- ceil (double x)
- {
- int rounding_mode, round_up;
-@@ -385,7 +385,7 @@ ceil (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- floor (double x)
- {
- int rounding_mode, round_down;
-@@ -408,7 +408,7 @@ floor (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- rint (double x)
- {
- int rounding_mode, round_nearest;
-@@ -430,7 +430,7 @@ rint (double x)
- return value;
- }
-
--__inline extern double
-+__inline double
- fmod (double x, double y)
- {
- double value;
-@@ -442,7 +442,7 @@ fmod (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- drem (double x, double y)
- {
- double value;
-@@ -454,7 +454,7 @@ drem (double x, double y)
- return value;
- }
-
--__inline extern double
-+__inline double
- scalb (double x, int n)
- {
- double value;
-@@ -466,7 +466,7 @@ scalb (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- logb (double x)
- {
- double exponent;
-@@ -477,7 +477,7 @@ logb (double x)
- return exponent;
- }
-
--__inline extern double
-+__inline double
- ldexp (double x, int n)
- {
- double value;
-@@ -489,7 +489,7 @@ ldexp (double x, int n)
- return value;
- }
-
--__inline extern double
-+__inline double
- frexp (double x, int *exp)
- {
- double float_exponent;
-@@ -514,7 +514,7 @@ frexp (double x, int *exp)
- return mantissa;
- }
-
--__inline extern double
-+__inline double
- modf (double x, double *ip)
- {
- double temp;
-diff --git a/gcc/config/m68k/predicates.md b/gcc/config/m68k/predicates.md
-index 186436c42b77..9533e65ceaab 100644
---- gcc/config/m68k/predicates.md
-+++ gcc/config/m68k/predicates.md
-@@ -30,6 +30,10 @@
- || GET_CODE (XEXP (op, 0)) == LABEL_REF
- || GET_CODE (XEXP (op, 0)) == CONST))
- return 1;
-+#ifdef TARGET_AMIGA
-+ if (flag_pic >= 3 && amiga_is_const_pic_ref(op))
-+ return 0;
-+#endif
- return general_operand (op, mode);
- })
-
-diff --git a/gcc/config/m68k/t-amigaos b/gcc/config/m68k/t-amigaos
-new file mode 100755
-index 000000000000..bf9c5279d04f
---- /dev/null
-+++ gcc/config/m68k/t-amigaos
-@@ -0,0 +1,28 @@
-+# Makefile fragment for AmigaOS target.
-+
-+# Extra object file linked to the cc1* executables.
-+amigaos.o: $(srcdir)/config/m68k/amigaos.c $(CONFIG_H)
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
-+
-+# Additional target dependent options for compiling libgcc.a. This just
-+# ensures that we don't compile libgcc* with anything other than a
-+# fixed stack.
-+
-+#TARGET_LIBGCC2_CFLAGS = -mfixedstack
-+
-+### begin-GG-local: dynamic libraries
-+# Extra objects that get compiled and linked to collect2
-+
-+EXTRA_COLLECT2_OBJS = amigacollect2.o
-+
-+# Build supplimentary AmigaOS target support file for collect2
-+amigacollect2.o: amigacollect2.c
-+ $(CXX) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+ -DA2IXDIR_PREFIX=\"$(prefix)/share/a2ixlibrary\" $< $(OUTPUT_OPTION)
-+### end-GG-local
-+
-+# Support for building multiple version of libgcc, libquadmath, libobjc and
libstdc++-v3
-+MULTILIB_OPTIONS = m68020 fbaserel/fbaserel32
-+MULTILIB_DIRNAMES = libm020 libb libb32
-+MULTILIB_EXTRA_OPTS = noixemul
-+MULTILIB_EXCEPTIONS = fbaserel32
-\ No newline at end of file
-diff --git a/gcc/config/m68k/x-amigaos b/gcc/config/m68k/x-amigaos
-new file mode 100755
-index 000000000000..a8f60b80f9f4
---- /dev/null
-+++ gcc/config/m68k/x-amigaos
-@@ -0,0 +1,104 @@
-+# Makefile fragment for AmigaOS host
-+
-+# Each compilation environment (Manx, Dice, GCC, SAS/C, etc) provides its
-+# own equivalent of the UNIX /usr/include tree. For gcc, the standard headers
-+# are in /gg/include and system specific headers are in /gg/os-include.
-+# Use these paths for fixincludes.
-+
-+SYSTEM_HEADER_DIR = $(prefix)/include
-+
-+# Uncomment the following macro to get a resident GCC. We don't do it
-+# by default, since we want to support users with mc68000.
-+# WARNING! If you uncomment this, you MUST add the same flags to the
-+# libiberty's Makefile (libiberty is now linked into GCC executables).
-+
-+#RESIDENT = -m68020 -resident32
-+
-+# Additional host flags that are not used when compiling with GCC_FOR_TARGET,
-+# such as when compiling the libgcc* runtime archives. GCC uses stack
-+# a lot, and since AmigaOS provides processes with a small, fixed size
-+# stack, we have to generate code that will extend it whenever necessary.
-+
-+XCFLAGS = -mstackextend $(RESIDENT)
-+
-+# AmigaOS supports "AmigaGuide(R)" hypertext files. For GCC, these are
-+# build with a custom "makeinfo".
-+
-+# Arrange for guides to be build with GCC, in the build directory.
-+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_DOC_TARGETS = guide gcc-amigaos-doc
-+### end-GG-local
-+
-+# Actually build guides
-+
-+guide:: doc/cpp.guide doc/gcc.guide doc/gccint.guide \
-+ doc/gccinstall.guide doc/cppinternals.guide
-+
-+doc/cpp.guide: $(TEXI_CPP_FILES)
-+doc/gcc.guide: $(TEXI_GCC_FILES)
-+doc/gccint.guide: $(TEXI_GCCINT_FILES)
-+doc/cppinternals.guide: $(TEXI_CPPINT_FILES)
-+
-+doc/%.guide: %.texi
-+ if [ x$(BUILD_INFO) = xinfo ]; then \
-+ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
-+ -I $(docdir)/include -o $@ $<; \
-+ fi
-+
-+# Duplicate entry to handle renaming of gccinstall.guide
-+doc/gccinstall.guide: $(TEXI_GCCINSTALL_FILES)
-+ if [ x$(BUILD_INFO) = xinfo ]; then \
-+ $(MAKEINFO) --amiga $(MAKEINFOFLAGS) -I $(docdir) \
-+ -I $(docdir)/include -o $@ install.texi; \
-+ fi
-+
-+# Arrange for guides to be installed with GCC.
-+
-+### begin-GG-local: gcc-amigaos
-+#EXTRA_INSTALL_TARGETS = install-guide install-gcc-amigaos-doc
-+### end-GG-local
-+
-+# Where the guide files go
-+
-+guidedir = $(prefix)/guide
-+
-+# Actually install guides.
-+
-+installdirs-guide:
-+ $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(guidedir)
-+
-+install-guide: doc installdirs-guide \
-+ $(DESTDIR)$(guidedir)/cpp.guide \
-+ $(DESTDIR)$(guidedir)/gcc.guide \
-+ $(DESTDIR)$(guidedir)/cppinternals.guide \
-+ $(DESTDIR)$(guidedir)/gccinstall.guide \
-+ $(DESTDIR)$(guidedir)/gccint.guide
-+
-+$(DESTDIR)$(guidedir)/%.guide: doc/%.guide installdirs-guide
-+ rm -f $@
-+ if [ -f $< ]; then \
-+ for f in $(<)*; do \
-+ realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \
-+ $(INSTALL_DATA) $$f $(DESTDIR)$(guidedir)/$$realfile; \
-+ chmod a-x $(DESTDIR)$(guidedir)/$$realfile; \
-+ done; \
-+ else true; fi
-+
-+### begin-GG-local: gcc-amigaos
-+# Build and install gcc-amigaos.guide - documentation specific to the
-+# AmigaOS port of GCC.
-+
-+gcc-amigaos-doc:: doc/gcc-amigaos.info doc/gcc-amigaos.guide
-+
-+doc/gcc-amigaos.info doc/gcc-amigaos.guide: gcc-amigaos.texi
-+
-+install-gcc-amigaos-doc: doc installdirs installdirs-guide \
-+ $(DESTDIR)$(infodir)/gcc-amigaos.info \
-+ $(DESTDIR)$(guidedir)/gcc-amigaos.guide
-+### end-GG-local
-+
-+host-amigaos.o : $(srcdir)/config/m68k/host-amigaos.c $(CONFIG_H) $(SYSTEM_H) \
-+ coretypes.h hosthooks.h hosthooks-def.h toplev.h diagnostic.h
-+ $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
-+ $(srcdir)/config/m68k/host-amigaos.c
-diff --git a/gcc/config/m68k/xm-amigaos.h b/gcc/config/m68k/xm-amigaos.h
-new file mode 100755
-index 000000000000..bb571ba040b3
---- /dev/null
-+++ gcc/config/m68k/xm-amigaos.h
-@@ -0,0 +1,64 @@
-+/* Configuration for GNU C-compiler for m68k Amiga, running AmigaOS.
-+ Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003
-+ Free Software Foundation, Inc.
-+ Contributed by Markus M. Wild (wild(a)amiga.physik.unizh.ch).
-+
-+This file is part of GCC.
-+
-+GCC is free software; you can redistribute it and/or modify
-+it under the terms of the GNU General Public License as published by
-+the Free Software Foundation; either version 2, or (at your option)
-+any later version.
-+
-+GCC is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with GCC; see the file COPYING. If not, write to
-+the Free Software Foundation, 59 Temple Place - Suite 330,
-+Boston, MA 02111-1307, USA. */
-+
-+#ifndef _FCNTL_H_
-+#include <fcntl.h>
-+#endif
-+
-+/* AmigaOS specific headers, such as from the Native Developer Update kits,
-+ go in SYSTEM_INCLUDE_DIR. STANDARD_INCLUDE_DIR is the equivalent of
-+ Unix "/usr/include". All other include paths are set in Makefile. */
-+
-+#define SYSTEM_INCLUDE_DIR "/gg/os-include"
-+#define STANDARD_INCLUDE_DIR "/gg/include"
-+
-+#define STANDARD_EXEC_PREFIX_1 "/gg/libexec/gcc/"
-+#define STANDARD_EXEC_PREFIX_2 "/gg/lib/gcc/"
-+#define STANDARD_STARTFILE_PREFIX_1 "/gg/lib/"
-+#define STANDARD_STARTFILE_PREFIX_2 "/gg/lib/"
-+
-+/* The AmigaOS stores file names with regard to upper/lower case, but actions
-+ on existing files are case independent on the standard filesystems.
-+
-+ A good example of where this causes problems is the conflict between the C
-+ include file <string.h> and the C++ include file <String.h>, where the
C++
-+ include file dir is searched first and thus causes includes of <string.h>
-+ to include <String.h> instead.
-+
-+ In order to solve this problem we define the macro OPEN_CASE_SENSITIVE as
-+ the name of the function that takes the same args as open() and does case
-+ dependent opens. */
-+
-+#define OPEN_CASE_SENSITIVE(NAME, FLAGS, MODE) open ((NAME), (FLAGS) | O_CASE, (MODE))
-+
-+/* On the AmigaOS, there are two pathname separators, '/' (DIR_SEPARATOR)
-+ and ':' (VOL_SEPARATOR). DIR_SEPARATOR defaults to the correct
-+ character, so we don't have to explicitly set it. */
-+
-+#define DIR_SEPARATOR '/'
-+#define VOL_SEPARATOR ':'
-+#define DIR_SEPARATOR_2 VOL_SEPARATOR
-+
-+/* Zap PREFIX_INCLUDE_DIR, since with the AmigaOS port it is the same as
-+ STANDARD_INCLUDE_DIR. */
-+
-+#undef PREFIX_INCLUDE_DIR
-diff --git a/gcc/coretypes.h b/gcc/coretypes.h
-index 12067fdf5348..f0f069f6afa2 100644
---- gcc/coretypes.h
-+++ gcc/coretypes.h
-@@ -52,9 +52,9 @@ typedef const struct bitmap_head *const_bitmap;
- struct simple_bitmap_def;
- typedef struct simple_bitmap_def *sbitmap;
- typedef const struct simple_bitmap_def *const_sbitmap;
--struct rtx_def;
--typedef struct rtx_def *rtx;
--typedef const struct rtx_def *const_rtx;
-+class rtx_def;
-+typedef class rtx_def *rtx;
-+typedef const class rtx_def *const_rtx;
-
- /* Subclasses of rtx_def, using indentation to show the class
- hierarchy, along with the relevant invariant.
-diff --git a/gcc/df-scan.c b/gcc/df-scan.c
-index 98de84405428..1f23452afe19 100644
---- gcc/df-scan.c
-+++ gcc/df-scan.c
-@@ -1807,6 +1807,12 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
- df_ref *ref_ptr;
- struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
-
-+ if (DF_REF_FLAGS_IS_SET(the_ref, DF_HARD_REG_LIVE))
-+ {
-+ --df->hard_regs_live_count[DF_REF_REGNO(the_ref)];
-+ ++df->hard_regs_live_count[new_regno];
-+ }
-+
- DF_REF_REGNO (the_ref) = new_regno;
- DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];
-
-diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
-index f241073866b4..566aaaf4e370 100644
---- gcc/dwarf2out.c
-+++ gcc/dwarf2out.c
-@@ -451,7 +451,7 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- /*global=*/1);
- lsda_encoding = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,
- /*global=*/0);
-- flags = ((! flag_pic
-+ flags = (( (!flag_pic || flag_pic > 2)
- || ((fde_encoding & 0x70) != DW_EH_PE_absptr
- && (fde_encoding & 0x70) != DW_EH_PE_aligned
- && (per_encoding & 0x70) != DW_EH_PE_absptr
-@@ -469,6 +469,16 @@ switch_to_eh_frame_section (bool back ATTRIBUTE_UNUSED)
- eh_frame_section = ((flags == SECTION_WRITE)
- ? data_section : readonly_data_section);
- #endif /* EH_FRAME_SECTION_NAME */
-+
-+#ifdef TARGET_AMIGA
-+ switch_to_section (data_section);
-+ fputs("\t__EH_FRAME_OBJECT__:\n\t.long 0\n\t.long 0\n\t.long 0\n\t.long
0\n\t.long 0\n\t.long 0\n", asm_out_file);
-+ fputs("\t.stabs
\"__EH_FRAME_OBJECTS__\",24,0,0,__EH_FRAME_OBJECT__\n", asm_out_file);
-+
-+ switch_to_section (eh_frame_section);
-+ ASM_OUTPUT_LABEL (asm_out_file, "_EH_FRAME_BEGIN__");
-+ fputs("\t.stabs
\"__EH_FRAME_BEGINS__\",22,0,0,__EH_FRAME_BEGIN__\n", asm_out_file);
-+#endif
- }
-
- switch_to_section (eh_frame_section);
-diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
-index 0fcd9d95e5b4..b2a18e7e4188 100644
---- gcc/emit-rtl.c
-+++ gcc/emit-rtl.c
-@@ -2123,7 +2123,11 @@ change_address_1 (rtx memref, machine_mode mode, rtx addr, int
validate,
- if (validate && !lra_in_progress)
- {
- if (reload_in_progress || reload_completed)
-- gcc_assert (memory_address_addr_space_p (mode, addr, as));
-+ {
-+ bool r = memory_address_addr_space_p (mode, addr, as);
-+ if (!r) debug_rtx(addr);
-+ gcc_assert (r);
-+ }
- else
- addr = memory_address_addr_space (mode, addr, as);
- }
-diff --git a/gcc/except.c b/gcc/except.c
-index 2a1073f80cc4..194478f8454c 100644
---- gcc/except.c
-+++ gcc/except.c
-@@ -142,6 +142,7 @@ along with GCC; see the file COPYING3. If not see
- #include "cfgloop.h"
- #include "builtins.h"
- #include "tree-hash-traits.h"
-+#include "target-def.h"
-
- static GTY(()) int call_site_base;
-
-@@ -2850,14 +2851,14 @@ switch_to_exception_section (const char * ARG_UNUSED (fnname))
- it linkonce if we have COMDAT groups to tie them together. */
- if (DECL_COMDAT_GROUP (current_function_decl) && HAVE_COMDAT_GROUP)
- flags |= SECTION_LINKONCE;
-- sprintf (section_name, ".gcc_except_table.%s", fnname);
-+ sprintf (section_name, TARGET_GCC_EXCEPT_TABLE_S, fnname);
- s = get_section (section_name, flags, current_function_decl);
- free (section_name);
- }
- else
- #endif
- exception_section
-- = s = get_section (".gcc_except_table", flags, NULL);
-+ = s = get_section (TARGET_GCC_EXCEPT_TABLE, flags, NULL);
- }
- else
- exception_section
-diff --git a/gcc/final.c b/gcc/final.c
-index 55cf509611f7..fa8b2964a40d 100644
---- gcc/final.c
-+++ gcc/final.c
-@@ -2151,6 +2151,7 @@ call_from_call_insn (rtx_call_insn *insn)
- SEEN is used to track the end of the prologue, for emitting
- debug information. We force the emission of a line note after
- both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG. */
-+rtx_insn * current_insn;
-
- rtx_insn *
- final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
-@@ -2160,6 +2161,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p
ATTRIBUTE_UNUSED,
- rtx set;
- #endif
- rtx_insn *next;
-+ current_insn = insn;
-
- insn_counter++;
-
-@@ -3622,6 +3624,12 @@ do_assembler_dialects (const char *p, int *dialect)
- void
- output_asm_insn (const char *templ, rtx *operands)
- {
-+ extern bool be_very_verbose;
-+ extern void append_reg_usage(FILE *, rtx_insn *);
-+
-+ extern bool dump_reg_track;
-+ void append_reg_cache (FILE * f, rtx_insn * insn);
-+
- const char *p;
- int c;
- #ifdef ASSEMBLER_DIALECT
-@@ -3778,6 +3786,11 @@ output_asm_insn (const char *templ, rtx *operands)
- putc (c, asm_out_file);
- }
-
-+ if (be_very_verbose)
-+ append_reg_usage(asm_out_file, current_insn);
-+ if (dump_reg_track)
-+ append_reg_cache(asm_out_file, current_insn);
-+
- /* Write out the variable names for operands, if we know them. */
- if (flag_verbose_asm)
- output_asm_operand_names (operands, oporder, ops);
-@@ -3995,6 +4008,7 @@ output_addr_const (FILE *file, rtx x)
- if (targetm.asm_out.output_addr_const_extra (file, x))
- break;
-
-+ debug_rtx(current_output_insn);
- output_operand_lossage ("invalid expression as operand");
- }
- }
-diff --git a/gcc/function.c b/gcc/function.c
-index 6942a504127f..ebe3e1c37121 100644
---- gcc/function.c
-+++ gcc/function.c
-@@ -39,9 +39,9 @@ along with GCC; see the file COPYING3. If not see
- #include "rtl.h"
- #include "tree.h"
- #include "gimple-expr.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "df.h"
--#include "tm_p.h"
- #include "stringpool.h"
- #include "expmed.h"
- #include "optabs.h"
-diff --git a/gcc/gcc.c b/gcc/gcc.c
-index 85ea19bd3a09..a4da7d515ce5 100644
---- gcc/gcc.c
-+++ gcc/gcc.c
-@@ -10107,3 +10107,40 @@ driver_get_configure_time_options (void (*cb) (const char
*option,
- obstack_free (&obstack, NULL);
- n_switches = 0;
- }
-+
-+#ifdef TARGET_AMIGA
-+const char * amiga_m68k_prefix_func(int argc, const char ** argv) {
-+ char * p = 0;
-+ if (standard_libexec_prefix)
-+ {
-+ char * glp = concat(standard_libexec_prefix, "", NULL);
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ *p = 0;
-+ p = strrchr(glp, '/');
-+ if (p)
-+ {
-+ p[1] = 0;
-+ p = concat(glp, "m68k-unknown-amigaos/", NULL);
-+ }
-+ }
-+ }
-+ free(glp);
-+ }
-+ if (!p)
-+ p = concat("../../../../", "", NULL);
-+
-+ for (int i = 0; i < argc; ++i) {
-+ char * q = concat(p, argv[i], NULL);
-+ free(p);
-+ p = q;
-+ }
-+// printf("amiga_m68k_prefix_func='%s'\n", p);
-+ return p;
-+}
-+#endif
-diff --git a/gcc/gcse.c b/gcc/gcse.c
-index 5b2c96ecb5a6..f74e733f9337 100644
---- gcc/gcse.c
-+++ gcc/gcse.c
-@@ -4075,7 +4075,9 @@ pass_rtl_pre::gate (function *fun)
- {
- return optimize > 0 && flag_gcse
- && !fun->calls_setjmp
-+#ifndef TARGET_AMIGA
- && optimize_function_for_speed_p (fun)
-+#endif
- && dbg_cnt (pre);
- }
-
-@@ -4118,6 +4120,9 @@ class pass_rtl_hoist : public rtl_opt_pass
- bool
- pass_rtl_hoist::gate (function *)
- {
-+#ifdef TARGET_AMIGA
-+ return false;
-+#else
- return optimize > 0 && flag_gcse
- && !cfun->calls_setjmp
- /* It does not make sense to run code hoisting unless we are optimizing
-@@ -4125,6 +4130,7 @@ pass_rtl_hoist::gate (function *)
- bigger if we did PRE (when optimizing for space, we don't run PRE). */
- && optimize_function_for_size_p (cfun)
- && dbg_cnt (hoist);
-+#endif
- }
-
- } // anon namespace
-diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
-index d711530d0535..4f08f81a3ae0 100644
---- gcc/ginclude/stddef.h
-+++ gcc/ginclude/stddef.h
-@@ -325,6 +325,7 @@ typedef __rune_t rune_t;
- #define __WCHAR_TYPE__ int
- #endif
- #ifndef __cplusplus
-+#define _WCHAR_T_ int
- typedef __WCHAR_TYPE__ wchar_t;
- #endif
- #endif
-diff --git a/gcc/hwint.h b/gcc/hwint.h
-index 4dd255d486c5..d5296a81d08e 100644
---- gcc/hwint.h
-+++ gcc/hwint.h
-@@ -295,7 +295,7 @@ abs_hwi (HOST_WIDE_INT x)
- inline unsigned HOST_WIDE_INT
- absu_hwi (HOST_WIDE_INT x)
- {
-- return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(unsigned HOST_WIDE_INT)x;
-+ return x >= 0 ? (unsigned HOST_WIDE_INT)x : -(signed HOST_WIDE_INT)x;
- }
-
- #endif /* ! GCC_HWINT_H */
-diff --git a/gcc/ipa-chkp.c b/gcc/ipa-chkp.c
-index 86c48f14f64d..dc72a5f21021 100644
---- gcc/ipa-chkp.c
-+++ gcc/ipa-chkp.c
-@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
-+#include "target.h"
- #include "tree.h"
- #include "gimple.h"
- #include "tree-pass.h"
-diff --git a/gcc/opts.c b/gcc/opts.c
-index 8f9862db57c2..6a87349e6a70 100644
---- gcc/opts.c
-+++ gcc/opts.c
-@@ -530,8 +530,10 @@ static const struct default_options default_options_table[] =
- { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
-+#ifndef TARGET_AMIGA
- { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
-+#endif
- { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
- { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
- { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
-diff --git a/gcc/passes.c b/gcc/passes.c
-index e89618111245..1d53bb23b1b0 100644
---- gcc/passes.c
-+++ gcc/passes.c
-@@ -2269,6 +2269,29 @@ override_gate_status (opt_pass *pass, tree func, bool
gate_status)
- }
-
-
-+void dump_insns(char const * name)
-+{
-+ rtx_insn *insn, *next;
-+ fprintf(stderr, "====================================\npass: %s\n", name);
-+ for (insn = get_insns(); insn; insn = next)
-+ {
-+ next = NEXT_INSN(insn);
-+ debug_rtx(insn);
-+#if 0
-+ if (NONJUMP_INSN_P (insn))
-+ {
-+ rtx set= single_set (insn);
-+ if (!set)
-+ continue;
-+
-+ if (amiga_is_const_pic_ref(SET_SRC(set)) && MEM_P(SET_DEST(set)))
-+ debug_rtx(insn);
-+ }
-+#endif
-+ }
-+}
-+
-+
- /* Execute PASS. */
-
- bool
-@@ -2278,6 +2301,9 @@ execute_one_pass (opt_pass *pass)
-
- bool gate_status;
-
-+ if (string_bbb_opts && strchr (string_bbb_opts, 'Y'))
-+ dump_insns(pass->name);
-+
- /* IPA passes are executed on whole program, so cfun should be NULL.
- Other passes need function context set. */
- if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
-diff --git a/gcc/passes.def b/gcc/passes.def
-index 7db9c9577cf4..61d0e4d47377 100644
---- gcc/passes.def
-+++ gcc/passes.def
-@@ -386,6 +386,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_gen_hsail);
-
- NEXT_PASS (pass_expand);
-+ NEXT_PASS (pass_bbb_baserel);
-
- NEXT_PASS (pass_rest_of_compilation);
- PUSH_INSERT_PASSES_WITHIN (pass_rest_of_compilation)
-@@ -458,6 +459,7 @@ along with GCC; see the file COPYING3. If not see
- NEXT_PASS (pass_cprop_hardreg);
- NEXT_PASS (pass_fast_rtl_dce);
- NEXT_PASS (pass_reorder_blocks);
-+ NEXT_PASS (pass_bbb_optimizations);
- NEXT_PASS (pass_branch_target_load_optimize2);
- NEXT_PASS (pass_leaf_regs);
- NEXT_PASS (pass_split_before_sched2);
-diff --git a/gcc/recog.c b/gcc/recog.c
-index 92b2aa31a777..73d1fd1b1336 100644
---- gcc/recog.c
-+++ gcc/recog.c
-@@ -3252,6 +3252,7 @@ peep2_attempt (basic_block bb, rtx_insn *insn, int match_len,
rtx_insn *attempt)
- /* If we are splitting an RTX_FRAME_RELATED_P insn, do not allow it to
- match more than one insn, or to be split into more than one insn. */
- old_insn = peep2_insn_data[peep2_current].insn;
-+
- if (RTX_FRAME_RELATED_P (old_insn))
- {
- bool any_note = false;
-diff --git a/gcc/regrename.c b/gcc/regrename.c
-old mode 100644
-new mode 100755
-index 9643f328ea3e..1ed6557ee713
---- gcc/regrename.c
-+++ gcc/regrename.c
-@@ -374,44 +374,45 @@ find_rename_reg (du_head_p this_head, enum reg_class super_class,
- = (enum reg_class) targetm.preferred_rename_class (super_class);
-
- /* Pick and check the register from the tied chain iff the tied chain
-- is not renamed. */
-+ is not renamed. */
- if (this_head->tied_chain && !this_head->tied_chain->renamed
- && check_new_reg_p (old_reg, this_head->tied_chain->regno,
- this_head, *unavailable))
- return this_head->tied_chain->regno;
-
- /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass
-- over registers that belong to PREFERRED_CLASS and try to find the
-- best register within the class. If that failed, we iterate in
-- the second pass over registers that don't belong to the class.
-- If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-- ascending order without any preference. */
-+ over registers that belong to PREFERRED_CLASS and try to find the
-+ best register within the class. If that failed, we iterate in
-+ the second pass over registers that don't belong to the class.
-+ If PREFERRED_CLASS is NO_REGS, we iterate over all registers in
-+ ascending order without any preference. */
- has_preferred_class = (preferred_class != NO_REGS);
- for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++)
- {
- int new_reg;
-- for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
-- {
-- if (has_preferred_class
-+ for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++)
-+ {
-+ if (has_preferred_class
- && (pass == 0)
- != TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
-- new_reg))
-- continue;
-+ new_reg))
-+ continue;
-
-- if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-- continue;
-+ if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable))
-+ continue;
-
-- if (!best_rename)
-- return new_reg;
-+ if (!best_rename)
-+ return new_reg;
-
-- /* In the first pass, we force the renaming of registers that
-- don't belong to PREFERRED_CLASS to registers that do, even
-- though the latters were used not very long ago. */
-- if ((pass == 0
-+ /* In the first pass, we force the renaming of registers that
-+ don't belong to PREFERRED_CLASS to registers that do, even
-+ though the latters were used not very long ago.
-+ Also use a register if no best_new_reg was found till now */
-+ if (((pass == 0 || !has_preferred_class)
- && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class],
- best_new_reg))
- || tick[best_new_reg] > tick[new_reg])
-- best_new_reg = new_reg;
-+ best_new_reg = new_reg;
- }
- if (pass == 0 && best_new_reg != old_reg)
- break;
-@@ -897,7 +898,7 @@ regrename_analyze (bitmap bb_mask)
- if (!range_overlaps_hard_reg_set_p (live, chain->regno,
- chain->nregs))
- continue;
--
-+
- n_succs_used++;
-
- dest_ri = (struct bb_rename_info *)e->dest->aux;
-@@ -921,7 +922,7 @@ regrename_analyze (bitmap bb_mask)
- printed = true;
- fprintf (dump_file,
- " merging chains %d (->%d) and %d (->%d) [%s]\n",
-- k, incoming_chain->id, j, chain->id,
-+ k, incoming_chain->id, j, chain->id,
- reg_names[incoming_chain->regno]);
- }
-
-@@ -954,7 +955,7 @@ regrename_analyze (bitmap bb_mask)
- numbering in its subpatterns. */
-
- bool
--regrename_do_replace (struct du_head *head, int reg)
-+regrename_do_replace (struct du_head *head, int regno)
- {
- struct du_chain *chain;
- unsigned int base_regno = head->regno;
-@@ -962,19 +963,20 @@ regrename_do_replace (struct du_head *head, int reg)
-
- for (chain = head->first; chain; chain = chain->next_use)
- {
-- unsigned int regno = ORIGINAL_REGNO (*chain->loc);
-- struct reg_attrs *attr = REG_ATTRS (*chain->loc);
-- int reg_ptr = REG_POINTER (*chain->loc);
-+ unsigned int orig_regno = ORIGINAL_REGNO(*chain->loc);
-+ struct reg_attrs *attr = REG_ATTRS(*chain->loc);
-+ int reg_ptr = REG_POINTER(*chain->loc);
-
- if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) !=
base_regno)
-- validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
-- gen_rtx_UNKNOWN_VAR_LOC (), true);
-+ validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC(chain->insn)),
-+ gen_rtx_UNKNOWN_VAR_LOC (),
-+ true);
- else
- {
-- validate_change (chain->insn, chain->loc,
-- gen_raw_REG (GET_MODE (*chain->loc), reg), true);
-- if (regno >= FIRST_PSEUDO_REGISTER)
-- ORIGINAL_REGNO (*chain->loc) = regno;
-+ validate_change (chain->insn, chain->loc,
-+ gen_raw_REG (GET_MODE(*chain->loc), regno), true);
-+ if (orig_regno >= FIRST_PSEUDO_REGISTER)
-+ ORIGINAL_REGNO (*chain->loc) = orig_regno;
- REG_ATTRS (*chain->loc) = attr;
- REG_POINTER (*chain->loc) = reg_ptr;
- }
-@@ -983,10 +985,29 @@ regrename_do_replace (struct du_head *head, int reg)
- if (!apply_change_group ())
- return false;
-
-- mode = GET_MODE (*head->first->loc);
-+ mode = GET_MODE(*head->first->loc);
- head->renamed = 1;
-- head->regno = reg;
-- head->nregs = hard_regno_nregs[reg][mode];
-+ head->regno = regno;
-+ head->nregs = hard_regno_nregs[regno][mode];
-+
-+ /* SBF: also update the current df info, move from base_regno -> regno. */
-+ if (base_regno < FIRST_PSEUDO_REGISTER && regno <
FIRST_PSEUDO_REGISTER)
-+ for (chain = head->first; chain; chain = chain->next_use)
-+ {
-+ if (DEBUG_INSN_P (chain->insn) &&
VAR_LOC_UNKNOWN_P(INSN_VAR_LOCATION_LOC(chain->insn)))
-+ continue;
-+ /* undo regno patch - will be patched again */
-+ if (REGNO (*chain->loc) == regno)
-+ SET_REGNO(*chain->loc, base_regno);
-+ df_ref_change_reg_with_loc (*chain->loc, regno);
-+
-+ SET_REGNO(*chain->loc, regno);
-+ }
-+
-+ /* Mark the old regno as no longer used. */
-+ if (!df->hard_regs_live_count[base_regno])
-+ df_set_regs_ever_live (base_regno, false);
-+
- return true;
- }
-
-@@ -1912,7 +1933,6 @@ const pass_data pass_data_regrename =
- 0, /* todo_flags_start */
- TODO_df_finish, /* todo_flags_finish */
- };
--
- class pass_regrename : public rtl_opt_pass
- {
- public:
-@@ -1923,7 +1943,7 @@ class pass_regrename : public rtl_opt_pass
- /* opt_pass methods: */
- virtual bool gate (function *)
- {
-- return (optimize > 0 && (flag_rename_registers));
-+ return (optimize > 0 && (flag_rename_registers) &&
!TARGET_AMIGA);
- }
-
- virtual unsigned int execute (function *) { return regrename_optimize (); }
-diff --git a/gcc/target-def.h b/gcc/target-def.h
-index ec5e09e568e6..9fbfde121095 100644
---- gcc/target-def.h
-+++ gcc/target-def.h
-@@ -108,3 +108,11 @@
- #include "hooks.h"
- #include "targhooks.h"
- #include "insn-target-def.h"
-+
-+#ifndef TARGET_GCC_EXCEPT_TABLE
-+#define TARGET_GCC_EXCEPT_TABLE ".gcc_except_table"
-+#endif
-+
-+#ifndef TARGET_GCC_EXCEPT_TABLE_S
-+#define TARGET_GCC_EXCEPT_TABLE_S ".gcc_except_table.%s"
-+#endif
-diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
-index 28dac22add66..16aa71ca4ee4 100644
---- gcc/tree-chkp.c
-+++ gcc/tree-chkp.c
-@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
- #include "system.h"
- #include "coretypes.h"
- #include "backend.h"
-+#include "tm_p.h"
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
-index 5f5055d3a6c1..76c0996850f4 100644
---- gcc/tree-pass.h
-+++ gcc/tree-pass.h
-@@ -590,6 +590,8 @@ extern rtl_opt_pass *make_pass_branch_target_load_optimize2
(gcc::context
- *ctxt);
- extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_optimizations (gcc::context *ctxt);
-+extern rtl_opt_pass *make_pass_bbb_baserel (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
- extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
-diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
-index 9f09d30b1f91..ab9c0117b078 100644
---- gcc/var-tracking.c
-+++ gcc/var-tracking.c
-@@ -92,10 +92,10 @@
- #include "target.h"
- #include "rtl.h"
- #include "tree.h"
-+#include "tm_p.h"
- #include "cfghooks.h"
- #include "alloc-pool.h"
- #include "tree-pass.h"
--#include "tm_p.h"
- #include "insn-config.h"
- #include "regs.h"
- #include "emit-rtl.h"
-diff --git a/gcc/varasm.c b/gcc/varasm.c
-index b65f29c13a46..8ead5ec3fcbb 100644
---- gcc/varasm.c
-+++ gcc/varasm.c
-@@ -252,7 +252,6 @@ get_unnamed_section (unsigned int flags, void (*callback) (const void
*),
- sect->unnamed.callback = callback;
- sect->unnamed.data = data;
- sect->unnamed.next = unnamed_sections;
--
- unnamed_sections = sect;
- return sect;
- }
-@@ -2228,11 +2227,17 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
- else
- {
- /* Special-case handling of vtv comdat sections. */
-- if (sect->named.name
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED &&
sect->named.name
- && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
- handle_vtv_comdat_section (sect, decl);
- else
-- switch_to_section (sect);
-+ {
-+#ifdef TARGET_AMIGA
-+ if ((sect->common.flags & SECTION_STYLE_MASK) == SECTION_NAMED)
-+ sect->named.decl = decl;
-+#endif
-+ switch_to_section (sect);
-+ }
- if (align > BITS_PER_UNIT)
- ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
- assemble_variable_contents (decl, name, dont_output_data);
-@@ -4962,7 +4967,7 @@ output_constructor_regular_field (oc_local_state *local)
- if each element has the proper size. */
- if (local->field != NULL_TREE || local->index != NULL_TREE)
- {
-- if (fieldpos > local->total_bytes)
-+ if (fieldpos >= local->total_bytes)
- {
- assemble_zeros (fieldpos - local->total_bytes);
- local->total_bytes = fieldpos;
-diff --git a/libcpp/lex.c b/libcpp/lex.c
-index e5a0397f3099..c2131adeb38e 100644
---- libcpp/lex.c
-+++ libcpp/lex.c
-@@ -64,6 +64,10 @@ static tokenrun *next_tokenrun (tokenrun *);
-
- static _cpp_buff *new_buff (size_t);
-
-+/*
-+ * SBF: This flag is set if an asm statement is parsed, to support multiline strings in
__asm()
-+ */
-+int in_assembler_directive;
-
- /* Utility routine:
-
-@@ -1063,7 +1067,10 @@ _cpp_process_line_notes (cpp_reader *pfile, int in_comment)
- else if (note->type == 0)
- /* Already processed in lex_raw_string. */;
- else
-- abort ();
-+ {
-+// abort ();
-+ printf("ups: note type=%d\n", note->type);
-+ }
- }
- }
-
-@@ -1875,6 +1882,20 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar
*base)
- break;
- else if (c == '\n')
- {
-+ /*
-+ * SBF: allow multi-line strings
-+ * Ignore the line end and move to next line.
-+ * Only fail, if there is no next line
-+ */
-+ if (in_assembler_directive)
-+ {
-+ cpp_buffer *buffer = pfile->buffer;
-+ if (buffer->cur < buffer->rlimit)
-+ CPP_INCREMENT_LINE (pfile, 0);
-+ buffer->need_line = true;
-+ if (_cpp_get_fresh_line (pfile))
-+ continue;
-+ }
- cur--;
- /* Unmatched quotes always yield undefined behavior, but
- greedy lexing means that what appears to be an unterminated
-diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
-index f09b39b0e85f..39f91d1567b6 100644
---- libgcc/Makefile.in
-+++ libgcc/Makefile.in
-@@ -230,7 +230,7 @@ endif
- # Options to use when compiling libgcc2.a.
- #
- LIBGCC2_DEBUG_CFLAGS = -g
--LIBGCC2_CFLAGS = -O2 $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
-+LIBGCC2_CFLAGS = $(LIBGCC2_INCLUDES) $(GCC_CFLAGS) $(HOST_LIBGCC2_CFLAGS) \
- $(LIBGCC2_DEBUG_CFLAGS) -DIN_LIBGCC2 \
- -fbuilding-libgcc -fno-stack-protector \
- $(INHIBIT_LIBC_CFLAGS)
-@@ -284,7 +284,7 @@ INTERNAL_CFLAGS = $(CFLAGS) $(LIBGCC2_CFLAGS) $(HOST_LIBGCC2_CFLAGS)
\
- $(INCLUDES) @set_have_cc_tls@ @set_use_emutls@
-
- # Options to use when compiling crtbegin/end.
--CRTSTUFF_CFLAGS = -O2 $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \
-+CRTSTUFF_CFLAGS = $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) \
- $(NO_PIE_CFLAGS) -finhibit-size-directive -fno-inline -fno-exceptions \
- -fno-zero-initialized-in-bss -fno-toplevel-reorder -fno-tree-vectorize \
- -fbuilding-libgcc -fno-stack-protector $(FORCE_EXPLICIT_EH_REGISTRY) \
-diff --git a/libgcc/config.host b/libgcc/config.host
-index 6f6810cf0baf..7117e7983b53 100644
---- libgcc/config.host
-+++ libgcc/config.host
-@@ -816,6 +816,11 @@ m32r-*-linux*)
- m32rle-*-linux*)
- tmake_file="$tmake_file m32r/t-linux t-fdpbit"
- ;;
-+m68k-*-amiga*)
-+ tmake_file="$tmake_file m68k/t-glue m68k/t-floatlib soft-fp"
-+ CFLAGS="-Os"
-+# tmake_file="$tmake_file m68k/t-glue soft-fp"
-+ ;;
- m68k-*-elf* | fido-*-elf)
- tmake_file="$tmake_file m68k/t-floatlib"
- ;;
-diff --git a/libgcc/config/m68k/fpgnulib.c b/libgcc/config/m68k/fpgnulib.c
-index fe41edf26aa0..90926104d8fd 100644
---- libgcc/config/m68k/fpgnulib.c
-+++ libgcc/config/m68k/fpgnulib.c
-@@ -105,6 +105,7 @@ union long_double_long
-
- #ifndef EXTFLOAT
-
-+#ifdef __UNORDSF2
- int
- __unordsf2(float a, float b)
- {
-@@ -118,7 +119,9 @@ __unordsf2(float a, float b)
- return 1;
- return 0;
- }
-+#endif
-
-+#ifdef __UNORDDF2
- int
- __unorddf2(double a, double b)
- {
-@@ -134,7 +137,9 @@ __unorddf2(double a, double b)
- return 1;
- return 0;
- }
-+#endif
-
-+#ifdef __FLOATUNSIDF
- /* convert unsigned int to double */
- double
- __floatunsidf (unsigned long a1)
-@@ -167,7 +172,9 @@ __floatunsidf (unsigned long a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __FLOATSIDF
- /* convert int to double */
- double
- __floatsidf (long a1)
-@@ -213,7 +220,9 @@ __floatsidf (long a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __FLOATUNSISF
- /* convert unsigned int to float */
- float
- __floatunsisf (unsigned long l)
-@@ -221,7 +230,10 @@ __floatunsisf (unsigned long l)
- double foo = __floatunsidf (l);
- return foo;
- }
-+#endif
-
-+
-+#ifdef __FLOATSISF
- /* convert int to float */
- float
- __floatsisf (long l)
-@@ -229,7 +241,10 @@ __floatsisf (long l)
- double foo = __floatsidf (l);
- return foo;
- }
-+#endif
-+
-
-+#ifdef __EXTENDSFDF2
- /* convert float to double */
- double
- __extendsfdf2 (float a1)
-@@ -268,7 +283,9 @@ __extendsfdf2 (float a1)
-
- return dl.d;
- }
-+#endif
-
-+#ifdef __TRUNCDFSF2
- /* convert double to float */
- float
- __truncdfsf2 (double a1)
-@@ -336,7 +353,9 @@ __truncdfsf2 (double a1)
- fl.l = PACK (SIGND (dl1), exp, mant);
- return (fl.f);
- }
-+#endif
-
-+#ifdef __FIXDFSI
- /* convert double to int */
- long
- __fixdfsi (double a1)
-@@ -368,7 +387,9 @@ __fixdfsi (double a1)
-
- return (SIGND (dl1) ? -l : l);
- }
-+#endif
-
-+#ifdef __FIXSFSI
- /* convert float to int */
- long
- __fixsfsi (float a1)
-@@ -376,6 +397,7 @@ __fixsfsi (float a1)
- double foo = a1;
- return __fixdfsi (foo);
- }
-+#endif
-
- #else /* EXTFLOAT */
-
-@@ -396,6 +418,8 @@ float __truncdfsf2 (double);
- long __fixdfsi (double);
- long __fixsfsi (float);
-
-+#if !defined(EXTFLOATCMP)
-+
- int
- __unordxf2(long double a, long double b)
- {
-@@ -445,38 +469,6 @@ __extenddfxf2 (double d)
- return ldl.ld;
- }
-
--/* convert long double to double */
--double
--__truncxfdf2 (long double ld)
--{
-- register long exp;
-- register union double_long dl;
-- register union long_double_long ldl;
--
-- ldl.ld = ld;
-- /*printf ("xfdf in: %s\n", dumpxf (ld));*/
--
-- dl.l.upper = SIGNX (ldl);
-- if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle &&
!ldl.l.lower)
-- {
-- dl.l.lower = 0;
-- return dl.d;
-- }
--
-- exp = EXPX (ldl) - EXCESSX + EXCESSD;
-- /* ??? quick and dirty: keep `exp' sane */
-- if (exp >= EXPDMASK)
-- exp = EXPDMASK - 1;
-- dl.l.upper |= exp << (32 - (EXPDBITS + 1));
-- /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */
-- dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
-- dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1));
-- dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1);
--
-- /*printf ("xfdf out: %g\n", dl.d);*/
-- return dl.d;
--}
--
- /* convert a float to a long double */
- long double
- __extendsfxf2 (float f)
-@@ -549,6 +541,8 @@ __negxf2 (long double x1)
- return - (double) x1;
- }
-
-+#else
-+
- long
- __cmpxf2 (long double x1, long double x2)
- {
-@@ -591,5 +585,38 @@ __gexf2 (long double x1, long double x2)
- return __cmpdf2 ((double) x1, (double) x2);
- }
-
-+/* convert long double to double */
-+double
-+__truncxfdf2 (long double ld)
-+{
-+ register long exp;
-+ register union double_long dl;
-+ register union long_double_long ldl;
-+
-+ ldl.ld = ld;
-+ /*printf ("xfdf in: %s\n", dumpxf (ld));*/
-+
-+ dl.l.upper = SIGNX (ldl);
-+ if ((ldl.l.upper & ~SIGNBIT) == 0 && !ldl.l.middle &&
!ldl.l.lower)
-+ {
-+ dl.l.lower = 0;
-+ return dl.d;
-+ }
-+
-+ exp = EXPX (ldl) - EXCESSX + EXCESSD;
-+ /* ??? quick and dirty: keep `exp' sane */
-+ if (exp >= EXPDMASK)
-+ exp = EXPDMASK - 1;
-+ dl.l.upper |= exp << (32 - (EXPDBITS + 1));
-+ /* +1-1: add one for sign bit, but take one off for explicit-integer-bit */
-+ dl.l.upper |= (ldl.l.middle & MANTXMASK) >> (EXPDBITS + 1 - 1);
-+ dl.l.lower = (ldl.l.middle & MANTXMASK) << (32 - (EXPDBITS + 1 - 1));
-+ dl.l.lower |= ldl.l.lower >> (EXPDBITS + 1 - 1);
-+
-+ /*printf ("xfdf out: %g\n", dl.d);*/
-+ return dl.d;
-+}
-+#endif /* EXTFLOATCMP */
-+
- #endif /* !__mcoldfire__ */
- #endif /* EXTFLOAT */
-diff --git a/libgcc/config/m68k/t-floatlib b/libgcc/config/m68k/t-floatlib
-index 1ee8782d9fd2..2365433a59b3 100644
---- libgcc/config/m68k/t-floatlib
-+++ libgcc/config/m68k/t-floatlib
-@@ -1,11 +1,62 @@
--LIB1ASMSRC = m68k/lb1sf68.S
--LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-- _double _float _floatex \
-- _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-- _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-+#LIB1ASMSRC = m68k/lb1sf68.S
-+#LIB1ASMFUNCS = _mulsi3 _udivsi3 _divsi3 _umodsi3 _modsi3 \
-+# _double _float _floatex \
-+# _eqdf2 _nedf2 _gtdf2 _gedf2 _ltdf2 _ledf2 \
-+# _eqsf2 _nesf2 _gtsf2 _gesf2 _ltsf2 _lesf2
-+#
-
--LIB2ADD = $(srcdir)/config/m68k/fpgnulib.c xfgnulib.c
-+LIB2ADD = xfpgnulib.c xfpgnulib__unordsf2.c xfpgnulib__unorddf2.c \
-+ xfpgnulib__floatunsidf.c xfpgnulib__floatsidf.c xfpgnulib__floatunsisf.c \
-+ xfpgnulib__floatsisf.c xfpgnulib__extendsfdf2.c xfpgnulib__truncdfsf2.c \
-+ xfpgnulib__fixdfsi.c xfpgnulib__fixsfsi.c xfpgnulib__cmpxf2.c
-
--xfgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
-- echo '#define EXTFLOAT' > xfgnulib.c
-- cat $< >> xfgnulib.c
-+xfpgnulib__unordsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDSF2' > xfpgnulib__unordsf2.c
-+ cat $< >> xfpgnulib__unordsf2.c
-+
-+xfpgnulib__unorddf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __UNORDDF2' > xfpgnulib__unorddf2.c
-+ cat $< >> xfpgnulib__unorddf2.c
-+
-+xfpgnulib__floatunsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSIDF' > xfpgnulib__floatunsidf.c
-+ cat $< >> xfpgnulib__floatunsidf.c
-+
-+xfpgnulib__floatsidf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSIDF' > xfpgnulib__floatsidf.c
-+ cat $< >> xfpgnulib__floatsidf.c
-+
-+xfpgnulib__floatunsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATUNSISF' > xfpgnulib__floatunsisf.c
-+ cat $< >> xfpgnulib__floatunsisf.c
-+
-+xfpgnulib__floatsisf.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FLOATSISF' > xfpgnulib__floatsisf.c
-+ cat $< >> xfpgnulib__floatsisf.c
-+
-+xfpgnulib__extendsfdf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __EXTENDSFDF2' > xfpgnulib__extendsfdf2.c
-+ cat $< >> xfpgnulib__extendsfdf2.c
-+
-+xfpgnulib__truncdfsf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __TRUNCDFSF2' > xfpgnulib__truncdfsf2.c
-+ cat $< >> xfpgnulib__truncdfsf2.c
-+
-+xfpgnulib__fixdfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXDFSI' > xfpgnulib__fixdfsi.c
-+ cat $< >> xfpgnulib__fixdfsi.c
-+
-+xfpgnulib__fixsfsi.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define __FIXSFSI' > xfpgnulib__fixsfsi.c
-+ cat $< >> xfpgnulib__fixsfsi.c
-+
-+xfpgnulib.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define EXTFLOAT' > xfpgnulib.c
-+ cat $< >> xfpgnulib.c
-+
-+xfpgnulib__cmpxf2.c: $(srcdir)/config/m68k/fpgnulib.c
-+ echo '#define EXTFLOAT' > xfpgnulib__cmpxf2.c
-+ echo '#define EXTFLOATCMP' >> xfpgnulib__cmpxf2.c
-+ cat $< >> xfpgnulib__cmpxf2.c
-+
-\ No newline at end of file
-diff --git a/libgcc/unwind-dw2.c b/libgcc/unwind-dw2.c
-index 1fb6026d123f..7bf0e4236f64 100644
---- libgcc/unwind-dw2.c
-+++ libgcc/unwind-dw2.c
-@@ -260,6 +260,9 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
- }
-
- /* Overwrite the saved value for register INDEX in CONTEXT with VAL. */
-+#ifdef TARGET_AMIGA
-+static int overregs[16];
-+#endif
-
- inline void
- _Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
-@@ -271,6 +274,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index,
_Unwind_Word val)
- gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
- size = dwarf_reg_size_table[index];
-
-+#ifdef TARGET_AMIGA
-+ overregs[index] = val;
-+#endif
- if (_Unwind_IsExtendedContext (context) && context->by_value[index])
- {
- context->reg[index] = _Unwind_Get_Unwind_Context_Reg_Val (val);
-@@ -279,6 +285,9 @@ _Unwind_SetGR (struct _Unwind_Context *context, int index,
_Unwind_Word val)
-
- ptr = (void *) (_Unwind_Internal_Ptr) context->reg[index];
-
-+ if (!ptr)
-+ return;
-+
- if (size == sizeof(_Unwind_Ptr))
- * (_Unwind_Ptr *) ptr = val;
- else
-@@ -1612,10 +1621,10 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
- macro because __builtin_eh_return must be invoked in the context of
- our caller. */
-
--#define uw_install_context(CURRENT, TARGET) \
-+#define uw_install_context(CURRENT, TARGET, INDEX) \
- do \
- { \
-- long offset = uw_install_context_1 ((CURRENT), (TARGET)); \
-+ long offset = uw_install_context_1 ((CURRENT), (TARGET), (INDEX)); \
- void *handler = __builtin_frob_return_addr ((TARGET)->ra); \
- _Unwind_DebugHook ((TARGET)->cfa, handler); \
- __builtin_eh_return (offset, handler); \
-@@ -1624,7 +1633,8 @@ _Unwind_DebugHook (void *cfa __attribute__ ((__unused__)),
-
- static long
- uw_install_context_1 (struct _Unwind_Context *current,
-- struct _Unwind_Context *target)
-+ struct _Unwind_Context *target,
-+ int index ATTRIBUTE_UNUSED)
- {
- long i;
- _Unwind_SpTmp sp_slot;
-@@ -1659,7 +1669,75 @@ uw_install_context_1 (struct _Unwind_Context *current,
- else if (t && c && t != c)
- memcpy (c, t, dwarf_reg_size_table[i]);
- }
-+#ifdef __AMIGA__
-+ /* SBF: evil hack to patch the values for d0/d1 into the stack location.
-+ * search the movem insn and count the saved regs.
-+ * Now patch the values into location.
-+ * Always patch d0/d1 since override is always invoked for d0/d1.
-+ * Then patch all other regs which the above code omitted.
-+ */
-+ /* uw_install_context_1 is called from 4 different locations - each uses an unique
index.
-+ * So initialization is only done once.
-+ */
-+ static unsigned short counts[4];
-+ static unsigned short masks[4];
-+
-+ unsigned short count = 0;
-+ unsigned short reg_mask = masks[index];
-+ /* init each index once. */
-+ if (!reg_mask)
-+ {
-+ /* get the return address.*/
-+ unsigned short * sp = *(((unsigned short **)¤t) - 1);
-+ /* search the movem -x(a5),regs insn.*/
-+ for (;;)
-+ {
-+ unsigned short s = *sp++;
-+// printf("%04x ", s);
-+ gcc_assert(s != (unsigned short)0x4e75);// hit return? ouch!
-+ if (s == (unsigned short)0x4ced)
-+ break;
-+ }
-+ reg_mask = *sp;
-+ /* count saved regs */
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ ++count;
-+ m >>= 1;
-+ }
-+ masks[index] = reg_mask;
-+ counts[index] = count;
-+ }
-+ else
-+ count = counts[index];
-
-+ /* regs are saved below local vars -> start at current */
-+ int * p = ((int *)current) - count;
-+
-+ for (unsigned short i = 0, m = reg_mask; i < 16; ++i)
-+ {
-+ if (m & 1)
-+ {
-+ if (i <= 1 || (!current->reg[i] && (target->reg[i] ||
target->by_value[i])))
-+ {
-+ int old = *p;
-+ /* not set by the code above - set it here */
-+ if (i <= 1) // use the override values for d0/d1
-+ *p = overregs[i];
-+ else
-+ if (target->by_value[i])
-+ *p = (int)target->reg[i];
-+ else
-+ *p = *(int*)target->reg[i];
-+// printf("patch reg %d from %08lx to %08lx\n", i, old, *p);
-+ }
-+ ++p;
-+ }
-+ m >>= 1;
-+ }
-+
-+#endif
- /* If the current frame doesn't have a saved stack pointer, then we
- need to rely on EH_RETURN_STACKADJ_RTX to get our target stack
- pointer value reloaded. */
-diff --git a/libgcc/unwind.inc b/libgcc/unwind.inc
-index 7413b55e3fab..bf07725ac840 100644
---- libgcc/unwind.inc
-+++ libgcc/unwind.inc
-@@ -132,7 +132,7 @@ _Unwind_RaiseException(struct _Unwind_Exception *exc)
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 0);
- }
-
-
-@@ -208,7 +208,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc,
- if (code != _URC_INSTALL_CONTEXT)
- return code;
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 1);
- }
-
-
-@@ -233,7 +233,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 2);
- }
-
-
-@@ -258,7 +258,7 @@ _Unwind_Resume_or_Rethrow (struct _Unwind_Exception *exc)
-
- gcc_assert (code == _URC_INSTALL_CONTEXT);
-
-- uw_install_context (&this_context, &cur_context);
-+ uw_install_context (&this_context, &cur_context, 3);
- }
-
-
-diff --git a/libiberty/lrealpath.c b/libiberty/lrealpath.c
-index b27c8de990e9..78c06e46da58 100644
---- libiberty/lrealpath.c
-+++ libiberty/lrealpath.c
-@@ -73,7 +73,7 @@ extern char *canonicalize_file_name (const char *);
- #endif
-
- char *
--lrealpath (const char *filename)
-+__xlrealpath (const char *filename)
- {
- /* Method 1: The system has a compile time upper bound on a filename
- path. Use that and realpath() to canonicalize the name. This is
-@@ -155,3 +155,19 @@ lrealpath (const char *filename)
- /* This system is a lost cause, just duplicate the filename. */
- return strdup (filename);
- }
-+
-+
-+char *
-+lrealpath (const char *filename)
-+{
-+ char * r = __xlrealpath(filename);
-+#if defined (_WIN32)
-+ if (strncmp(r, "/cygdrive/", 10) == 0)
-+ {
-+ r[9] = r[10];
-+ r[10] = ':';
-+ r = strdup(&r[9]);
-+ }
-+#endif
-+ return r;
-+}
-diff --git a/libobjc/configure b/libobjc/configure
-index 55fcc33dbe2d..a60258f422d8 100755
---- libobjc/configure
-+++ libobjc/configure
-@@ -7637,7 +7637,8 @@ $as_echo_n "checking for $compiler option to produce PIC...
" >&6; }
- # FIXME: we need at least 68020 code to build shared libraries, but
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
-- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ #lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
- ;;
- esac
- ;;
-diff --git a/libobjc/objc/objc.h b/libobjc/objc/objc.h
-index 37391a446bb0..6c73f53290e8 100644
---- libobjc/objc/objc.h
-+++ libobjc/objc/objc.h
-@@ -52,7 +52,11 @@ extern "C" {
- Important: this could change and we could switch to 'typedef bool
- BOOL' in the future. Do not depend on the type of BOOL. */
- #undef BOOL
-+#ifdef AMIGA
-+typedef short BOOL;
-+#else
- typedef unsigned char BOOL;
-+#endif
-
- #define YES (BOOL)1
- #define NO (BOOL)0
-diff --git a/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
b/libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-index 903de5625d77..ed0c757d42f8 100644
---- libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-+++ libstdc++-v3/config/os/newlib/ctype_configure_char.cc
-@@ -65,6 +65,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
- _M_narrow_ok = 0;
- }
-
-+#ifdef __AMIGA__
-+ ctype<char>::~ctype()
-+ {
-+ _S_destroy_c_locale(_M_c_locale_ctype);
-+ if (_M_del)
-+ delete[] this->table();
-+ }
-+#endif
-+
- char
- ctype<char>::do_toupper(char __c) const
- {
-diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
-index 9bf152a01573..f162705f2625 100755
---- libstdc++-v3/configure
-+++ libstdc++-v3/configure
-@@ -8636,6 +8636,8 @@ $as_echo_n "checking for $compiler option to produce PIC...
" >&6; }
- # adding the `-m68020' flag to GCC prevents building anything better,
- # like `-m68040'.
- lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
-+ enable_shared=no
-+ CXXFLAGS="$CXXFLAGS -noixemul"
- ;;
- esac
- ;;
-@@ -28883,6 +28885,10 @@ else
-
- # Base decisions on target environment.
- case "${host}" in
-+ m68k-*-*)
-+ # Nothing to do here.
-+ ;;
-+
- arm*-*-symbianelf*)
- # This is a freestanding configuration; there is nothing to do here.
- ;;
-diff --git a/libstdc++-v3/configure.host b/libstdc++-v3/configure.host
-index 304a7f5aff61..fde4a72bd31b 100644
---- libstdc++-v3/configure.host
-+++ libstdc++-v3/configure.host
-@@ -226,6 +226,11 @@ case "${host_os}" in
- os_include_dir="os/generic"
- atomicity_dir="cpu/generic"
- ;;
-+ amiga*)
-+ os_include_dir="os/newlib"
-+ CFLAGS="-Os -noixemul"
-+ CPPFLAGS="-Os -noixemul"
-+ ;;
- bsd*)
- # Plain BSD attempts to share FreeBSD files.
- os_include_dir="os/bsd/freebsd"
-diff --git a/libstdc++-v3/include/tr1/cstdint b/libstdc++-v3/include/tr1/cstdint
-index 7304d9008413..7d6ab77ce17a 100644
---- libstdc++-v3/include/tr1/cstdint
-+++ libstdc++-v3/include/tr1/cstdint
-@@ -30,7 +30,9 @@
- #define _GLIBCXX_TR1_CSTDINT 1
-
- #pragma GCC system_header
--
-+#ifdef AMIGA
-+#include <stdint.h>
-+#endif
- #include <bits/c++config.h>
-
- // For 8.22.1/1 (see C99, Notes 219, 220, 222)
-diff --git a/libstdc++-v3/src/c++11/ctype.cc b/libstdc++-v3/src/c++11/ctype.cc
-index fa370681dad5..f80e83034255 100644
---- libstdc++-v3/src/c++11/ctype.cc
-+++ libstdc++-v3/src/c++11/ctype.cc
-@@ -51,12 +51,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- const size_t ctype<char>::table_size;
-
-+#ifndef __AMIGA__
-+/* moved to ctype_configure_char */
- ctype<char>::~ctype()
- {
- _S_destroy_c_locale(_M_c_locale_ctype);
- if (_M_del)
- delete[] this->table();
- }
-+#endif
-
- // Fill in the narrowing cache and flag whether all values are
- // valid or not. _M_narrow_ok is set to 2 if memcpy can't
--
Cross-compilation toolchains and environments