summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Young <chris@unsatisfactorysoftware.co.uk>2018-01-21 23:53:45 +0000
committerChris Young <chris@unsatisfactorysoftware.co.uk>2018-07-23 18:41:06 +0100
commit8a8d2a77923f3e40a863272adeb828bccc8767c4 (patch)
tree4607c2a0c9fb1d999b43912f4e6a0d6398fbe5e8
parent8931d3e283aedea5247f1ed6d667c84ddeab72cb (diff)
downloadtoolchains-8a8d2a77923f3e40a863272adeb828bccc8767c4.tar.gz
toolchains-8a8d2a77923f3e40a863272adeb828bccc8767c4.tar.bz2
New approach
Fork bebbo's version of gcc, add our changes and create a tarball from that.
-rw-r--r--m68k-unknown-amigaos/Makefile8
-rw-r--r--m68k-unknown-amigaos/recipes/patches/gcc/gcc6.p11008
2 files changed, 4 insertions, 11012 deletions
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_TARBALL)
+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="&quot;${workspace_loc:/amigaos-cross-toolchain/.build-m68k/build/gcc-6/gcc}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;C:\cygwin\usr\include&quot;"/>
-+ </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="&quot;C:\cygwin\usr\include&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
-+ </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="&quot;C:\cygwin\usr\include&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/gcc-6/libcpp/include}&quot;"/>
-+ <listOptionValue builtIn="false" value="&quot;D:\develop\workspaces\c1\amigaos-cross-toolchain\.build-m68k\build\gcc-6\gcc&quot;"/>
-+ </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="&quot;C:\cygwin\usr\include&quot;"/>
-+ </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="&quot;C:\cygwin\usr\include&quot;"/>
-+ </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="&quot;C:\cygwin\usr\include&quot;"/>
-+ </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 &quot;${INPUTS}&quot;" 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 &quot;${INPUTS}&quot;" 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@amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra@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@amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra@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@amiga.physik.unizh.ch).
-+ Heavily modified by Kamil Iskra (iskra@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@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 "@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@netcom.com) and Fred Fish (fnf@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@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 **)&current) - 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