changeset 495:5b8871fd7503

Merged previous lwcc development branch into mainline.
author William Astle <lost@l-w.ca>
date Mon, 05 Aug 2019 21:27:09 -0600
parents 6073f4a33475 (diff) 836dc5371980 (current diff)
children a38542cf4cc6
files .hgignore Makefile
diffstat 135 files changed, 37645 insertions(+), 15064 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Mon Aug 05 21:07:14 2019 -0600
+++ b/.hgignore	Mon Aug 05 21:27:09 2019 -0600
@@ -9,6 +9,13 @@
 /lwobjdump$
 /lwar$
 /lwasm$
-/lwcc$
-/lwcc-cpp$
-/lwcc-cc$
+/lwcc/lwcc$
+/lwcc/lwcc-cpp$
+/lwcc/lwcc-cc
+
+# for windows
+\.suo$
+\.sdf$
+\.opensdf$
+\Debug$
+\Release$
--- a/.hgtags	Mon Aug 05 21:07:14 2019 -0600
+++ b/.hgtags	Mon Aug 05 21:27:09 2019 -0600
@@ -10,3 +10,12 @@
 38ecb99d78dd5177873ffb5a13e25295348bad9b lwtools-4.6
 65510f1574e4e729efac9f20003ef8d29118f6cf lwtools-4.7
 1dcc0b174e3b340702a33182acc6cf8274ccbe4e lwtools-4.8
+21ecf29b568ea6a9df18309f035be11bc5b955f8 lwtools-4.9
+f3592d276aedcf0c4dd5d81349b21f8ce2ebc3d1 lwtools-4.10
+fd96bb4a9c8d2451b85703e49edc136b560cd206 lwtools-4.11
+d7870f1e912196d96e606f7904db3e4f940ab4b7 lwtools-4.12
+6d48a45609e52e6ef3709a30578ad7086c768761 lwtools-4.13
+9f49f0966c1ec3c373b506aa38cc1f856bd4fdce lwtools-4.14
+40516fb9af079c21b1d80338a7ccb1500979fc9f lwtools-4.15
+a71206ed966c19b5e5b6d201ae62ce30141c0fda lwtools-4.16
+a83d1cdeeb619cf7113b7cc6b6a0f416b66a4aa8 lwtools-4.17
--- a/00README.txt	Mon Aug 05 21:07:14 2019 -0600
+++ b/00README.txt	Mon Aug 05 21:27:09 2019 -0600
@@ -1,3 +1,8 @@
+The official distribution point for lwtools is
+http://lwtools.projects.l-w.ca/. If you obtained this distribution from any
+other place, please visit the official site. You may have a modified or out
+of date version.
+
 This is LWTOOLS, a cross development system targetting the 6809 CPU.
 
 It consists of an assembler, lwasm, a linker, lwlink, and an archiver,
@@ -5,6 +10,10 @@
 have problems building, make sure you are using GNU make. Other make
 programs may work but GNU make is known to work.
 
+There is some source code support for building with Microsoft's compiler on
+Windows. However, this has been contributed by interested users and is not
+well tested. Indeed, the primary maintainer has no access to such a system.
+
 To see if a quick build will work, just type "make". If it works, you're
 ready to go ahead with "make install". This will install in /usr/local/bin.
 
@@ -13,3 +22,66 @@
 running on a fairly standard unix system with perl in /usr/bin/perl.
 
 See docs/ for additional information.
+
+CONTRIBUTING
+============
+
+If you wish to contribute patches or code to lwtools, please keep the
+following in mind.
+
+Style
+-----
+
+The code formatting style must match the rest of the lwtools code. Code
+submitted in the "1TBS" will be rejected out of hand. Attempts to convince
+me to change my mind on this point will be routed to /dev/null at best and
+likely met with extreme rudeness.
+
+C code should be formatted as follows:
+
+* All indentation uses a single TAB character for each step. That is a HARD
+  tab, not a series of spaces. TABs are assumed to be 4 characters though
+  that will largely impact only lining up comments and tabular code. If the
+  actual formatting of the code is critical, spaces may be used for that
+  formatting but the actual initial indentation of the lines MUST use TAB
+  characters.
+* The opening brace for a block appears on the line below the control
+  structure that introduces it. It appears lined up with the preceding line
+  and nothing else appears on the same line.
+* Closing braces appear on a line by themselves ordinarily. The exception is
+  the "while" keyword in a "do-while" statement appears on the same line as
+  the closing brace for the block.
+* Case labels are lined up with the enclosing block (one level back from the
+  code of the block). The same guideline applies for ordinarily labels.
+* No spaces surround parentheses, brackets, or the dot operator. No space
+  precedes a comma but a space should follow it. Other operators should
+  usually be surrounded by spaces. A space should separate a keyword from
+  any surrounding except for sizeof() which should be written like a
+  function call. There is no space between a function name and the start of
+  its parameter list.
+
+In general, study the existing source formatting and copy the style. This is
+what you should do anyway and the above should not be required.
+
+For code accepted to the contrib/ hierarchy, application of the above coding
+style may be less strict.
+
+Submitting
+----------
+
+When submitting code to lwtools, it should be submitted as a patch file (hg
+diff or diff -u). DO NOT submit entire source files. Remember, others may be
+working on changes, too, and your complete source files are difficult to
+merge with such situations. By submitting complete source files, you are
+making far more work for the maintainer and it is generally considered rude.
+
+Always specify what version of the source you based your patch on. If
+possible, work off the default branch in the mercurial repository. At the
+very least, make sure you are working with the most recent release.
+
+It is also worth checking with the maintainer before submitting a patch.
+There may be some reason why your pet feature is not present in the official
+release.
+
+Finally, be prepared to receive a list of deficiencies or requests for
+improvements or clarification of why or how you did something.
--- a/Makefile	Mon Aug 05 21:07:14 2019 -0600
+++ b/Makefile	Mon Aug 05 21:27:09 2019 -0600
@@ -44,12 +44,12 @@
 RANLIB := $(BUILDTPREFIX)$(RANLIB)
 endif
 
-CPPFLAGS += -I lwlib -DPACKAGE_STRING='"lwtools $(PACKAGE_VERSION)"'
+CPPFLAGS += -I lwlib -Icommon
 CPPFLAGS += -DPREFIX=$(PREFIX) -DLWCC_LIBDIR=$(LWCC_LIBDIR)
 CPPFLAGS += -DPROGSUFFIX=$(PROGSUFFIX)
-LDFLAGS += -L$(PWD)/lwlib -llw
+LDFLAGS += -Llwlib -llw
 
-CFLAGS ?= -O3 -Wall
+CFLAGS ?= -O3 -Wall -Wno-char-subscripts
 
 MAIN_TARGETS := lwasm/lwasm$(PROGSUFFIX) \
 	lwlink/lwlink$(PROGSUFFIX) \
@@ -79,11 +79,11 @@
 lwlink_srcs := $(addprefix lwlink/,$(lwlink_srcs))
 lwobjdump_srcs := $(addprefix lwlink/,$(lwobjdump_srcs))
 
-lwasm_srcs :=  debug.c input.c insn_bitbit.c insn_gen.c insn_indexed.c \
+lwasm_srcs := cycle.c debug.c input.c insn_bitbit.c insn_gen.c insn_indexed.c \
 	insn_inh.c insn_logicmem.c insn_rel.c insn_rlist.c insn_rtor.c insn_tfm.c \
 	instab.c list.c lwasm.c macro.c main.c os9.c output.c pass1.c pass2.c \
 	pass3.c pass4.c pass5.c pass6.c pass7.c pragma.c pseudo.c section.c \
-	struct.c symbol.c unicorns.c
+	struct.c symbol.c symdump.c unicorns.c
 lwasm_srcs := $(addprefix lwasm/,$(lwasm_srcs))
 
 lwasm_objs := $(lwasm_srcs:.c=.o)
@@ -222,9 +222,9 @@
 	@echo $* = $($*)
 
 .PHONY: install
-install:
-	install -d $(INSTALLBIN)
-	install $(MAIN_TARGETS) $(INSTALLBIN)
+install: $(MAIN_TARGETS)
+	install -d $(INSTALLDIR)
+	install $(MAIN_TARGETS) $(INSTALLDIR)
 	install -d $(LWCC_INSTALLLIBDIR)
 	install -d $(LWCC_INSTALLLIBDIR)/bin
 	install -d $(LWCC_INSTALLLIBDIR)/lib
@@ -243,24 +243,3 @@
 test: all test/runtests
 	@test/runtests
 
-.PHONY: manual
-manual: manual-html manual-htmlm manual-pdf
-
-.PHONY: manual-html
-manual-html: docs/manual/manual.html
-
-.PHONY: manual-htmlm
-manual-htmlm: docs/manual/index.html
-
-.PHONY: manual-pdf
-manual-pdf: docs/manual/manual.pdf
-
-docs/manual/manual.html: docs/manual.docbook.sgml
-	docbook2html -o docs -u docs/manual.docbook.sgml && mv docs/manual.docbook.html docs/manual/manual.html
-
-docs/manual/index.html: docs/manual.docbook.sgml
-	docbook2html -o docs/manual docsmanual.docbook.sgml
-
-docs/manual/manual.pdf: docs/manual.docbook.sgml
-	docbook2pdf -o docs -u docsmanual.docbook.sgml && mv docs/manual.docbook.pdf docs/manual/manual.pdf && rm -f docs/manual.docbook.html
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/common/version.h	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,27 @@
+/*
+lw_version.h
+
+Copyright © 2018 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 of the License, or (at your option) any later
+version.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef lw_version_h_seen___
+#define lw_version_h_seen___
+
+#define PACKAGE_STRING "lwtools 4.17"
+
+#endif /* lw_version_h_seen___ */
--- a/docs/Makefile	Mon Aug 05 21:07:14 2019 -0600
+++ b/docs/Makefile	Mon Aug 05 21:27:09 2019 -0600
@@ -1,8 +1,11 @@
 all:
-	hg rm manual/* || true
 	rm -f manual/*.pdf manual/*.html
 	docbook2html -o manual manual.docbook.sgml
 	docbook2html -u manual.docbook.sgml && mv manual.docbook.html manual/manual.html
 	docbook2pdf -u manual.docbook.sgml && mv manual.docbook.pdf manual/manual.pdf
 	rm -f manual.docbook.html
+
+maint:
+	hg rm --force manual/* || true
+	$(MAKE) all
 	hg add manual/*
--- a/docs/manual.docbook.sgml	Mon Aug 05 21:07:14 2019 -0600
+++ b/docs/manual.docbook.sgml	Mon Aug 05 21:27:09 2019 -0600
@@ -3,7 +3,8 @@
 <bookinfo>
 <title>LW Tool Chain</title>
 <author><firstname>William</firstname><surname>Astle</surname></author>
-<copyright><year>2009-2013</year><holder>William Astle</holder></copyright>
+<author><firstname>LWTools Contributors</firstname><surname></surname></author>
+<copyright><year>2009-2015</year><holder>William Astle and LWTools contributors</holder></copyright>
 </bookinfo>
 <chapter>
 
@@ -92,6 +93,83 @@
 </section>
 
 <section>
+<title>ASCII Hexadecimal</title>
+
+<para>
+This human-readable ASCII hexadecimal format consists of CR+LF terminated 
+lines of ASCII text. Each line has the following structure: a zero-padded 
+four-digit ASCII hex address, a colon separator, and one or more zero-padded
+two-digit hex values separated by commas. ASCII Hexadecimal format favors 
+paragraph-aligned addresses (i.e. a least significant address nybble value
+of zero). During output, the number of hex values on each line are adjusted
+to align the address of the next line on a paragraph boundary. The sequence 
+of addresses in the ASCII Hexadecimal file directly follows that of the source
+file; multiple ORG directives in the source code may result in out-of-sequence
+addresses in the ASCII Hexadecimal output.
+</para>
+
+<para>
+LWASM can output this format since version 4.10.
+</para>
+</section>
+
+<section>
+<title>Motorola S-Record</title>
+
+<para>
+This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+"S", an ASCII record type digit (0-9), a two-digit ASCII hex byte count, a 
+four-digit ASCII hex address, an optional sequence of two-digit ASCII hex data
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only S0, 
+S1, S5 and S9 record types. S1 records are limited to maximum of 16 data bytes
+in length, and  paragraph alignment of addresses is favored. The address
+sequence of the S-Records directly follows that of the source file; multiple
+ORG directives in the source code may result in out-of-sequence addresses in
+the S-Record output. 
+</para>
+
+<para>
+Motorola S-Record format is a standard ASCII format accepted by most memory
+device programming equipment. It is particularly useful when the assembled 
+code output is destined to reside within an EPROM or Flash memory device,
+for example.
+</para>
+
+<para>
+LWASM can output this format since version 4.10. LWLINK can output this format
+since version 4.11.
+</para>
+</section>
+
+<section>
+<title>Intel Hex</title>
+
+<para>
+This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+":", a two-digit ASCII hex byte count, a four-digit ASCII hex address, a two-
+digit ASCII hex record type, an optional sequence of two-digit ASCII hex data 
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only 00, 
+and 01 Intel Hex record types. Data records are limited to maximum of 16 
+data bytes in length, and paragraph alignment of addresses is favored. The 
+address sequence of the Intel hex records directly follows that of the source 
+file; multiple ORG directives in the source code may result in out-of-sequence 
+addresses in the Intel Hex output. 
+</para>
+
+<para>
+Intel Hex format is the other standard ASCII format accepted by most memory 
+device programming equipment, it and the Motorola S-Record format are used for
+similar purposes.
+</para>
+
+<para>
+LWASM can output this format since version 4.10.
+</para>
+</section>
+
+<section>
 <title>OS9 Modules</title>
 <para>
 
@@ -206,6 +284,18 @@
 on the 6309 processor. This is the default mode; this option is provided for
 completeness and to override preset command arguments.
 </para>
+<para>
+This option is the same as if the first line of the source code is "PRAGMA 6309".
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--6800compat</option></term>
+<listitem>
+<para>
+This is equivalent to <option>--pragma=6800compat</option>.</para>
+<para>This will enable recognition of 6800 compatibility instructions.</para>
 </listitem>
 </varlistentry>
 
@@ -215,7 +305,8 @@
 <listitem>
 <para>
 This will cause the assembler to reject instructions that are only available
-on the 6309 processor.
+on the 6309 processor. This actually has the effect of starting the assembler
+as though the first line of the source is "PRAGMA 6809".
 </para>
 </listitem>
 </varlistentry>
@@ -241,8 +332,10 @@
 <para>
 Select the output format. Valid values are <option>obj</option> for the
 object file target, <option>decb</option> for the DECB LOADM format,
-<option>os9</option> for creating OS9 modules, and <option>raw</option> for
-a raw binary.
+<option>os9</option> for creating OS9 modules, <option>raw</option> for
+a raw binary, <option>hex</option> for ASCII hexadecminal format, 
+<option>srec</option> for Motorola S-Record format, and <option>ihex</option>
+ for Intel Hex format.
 </para>
 </listitem>
 </varlistentry>
@@ -261,6 +354,21 @@
 </varlistentry>
 
 <varlistentry>
+<term><option>--symbol-dump[=file]</option></term>
+<listitem>
+<para>
+Cause LWASM to output the global symbol table in assembly source format. If
+<option>file</option> is specified, the table output will go to the specified
+file. Otherwise, it will go to the standard output stream. Local symbols will
+not be included. Incomplete symbols will be defined to zero with a comment
+indicating incompleteness. Symbols defined with SET will also be listed using
+SET in the symbol dump. However, if the symbol is defined multiple times, the
+order of the definitions in the dump file is undefined.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
 <term><option>--symbols</option></term>
 <term><option>-s</option></term>
 <listitem>
@@ -272,6 +380,26 @@
 </varlistentry>
 
 <varlistentry>
+<term><option>--symbols-nolocals</option></term>
+<listitem>
+<para>
+Behaves just like <option>--symbols</option> but with local labels omitted.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term><option>--map=FILE</option></term>
+<listitem>
+<para>
+
+This option generates a map file which can be used by debuggers and monitors to provide symbol information. A map file may be created independent of a listing file. (Patches are pending for MAME and exec09.)
+
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
 <term><option>--obj</option></term>
 <listitem>
 <para>
@@ -292,6 +420,13 @@
 </varlistentry>
 
 <varlistentry>
+<term><option>--no-output</option></term>
+<listitem>
+<para>Do assembly as usual but suppress generation of the output file.</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
 <term><option>--pragma=pragma</option></term>
 <term><option>-p pragma</option></term>
 <listitem>
@@ -337,6 +472,16 @@
 </listitem>
 </varlistentry>
 
+<varlistentry>
+<term><option>-t WIDTH</option></term>
+<term><option>--tabs=WIDTH</option></term>
+<listitem>
+<para>
+Specifies the handling of tabs in listing files. <option>--tabs=0</option>
+disables tab expansion. <option>--tabs=8</option> is the default setting.
+</para>
+</listitem>
+</varlistentry>
 
 <varlistentry>
 <term><option>--help</option></term>
@@ -384,16 +529,19 @@
 
 <section>
 <title>Dialects</title>
-<para>
-LWASM supports all documented MC6809 instructions as defined by Motorola. 
-It also supports all known HD6309 instructions.  While there is general
-agreement on the pneumonics for most of the 6309 instructions, there is some
-variance with the block transfer instructions. TFM for all four variations
-seems to have gained the most traction and, thus, this is the form that is
-recommended for LWASM. However, it also supports COPY, COPY-, IMP, EXP,
-TFRP, TFRM, TFRS, and TFRR. It further adds COPY+ as a synomym for COPY,
-IMPLODE for IMP, and EXPAND for EXP.
-</para>
+
+<para> LWASM supports all documented MC6809 instructions as defined by
+Motorola.  By default, this does not include any MC6800 compatibility
+instructions.  As of LWASM 4.11, those compatibility instructions can be
+enabled using the <parameter>--6800compat</parameter> option or the
+<parameter>6800compat</parameter> pragma.  It also supports all known HD6309
+instructions.  While there is general agreement on the pneumonics for most
+of the 6309 instructions, there is some variance with the block transfer
+instructions.  TFM for all four variations seems to have gained the most
+traction and, thus, this is the form that is recommended for LWASM. 
+However, it also supports COPY, COPY-, IMP, EXP, TFRP, TFRM, TFRS, and TFRR. 
+It further adds COPY+ as a synomym for COPY, IMPLODE for IMP, and EXPAND for
+EXP.  </para>
 
 <para>By default, LWASM accepts 6309 instructions. However, using the
 <parameter>--6809</parameter> parameter, you can cause it to throw errors on
@@ -715,7 +863,7 @@
 </varlistentry>
 
 <varlistentry>
-<term>FILL <parameter>size</parameter>,<parameter>byte</parameter></term>
+<term>FILL <parameter>byte</parameter>,<parameter>size</parameter></term>
 <listitem>
 
 <para>
@@ -739,10 +887,23 @@
 <listitem>
 <para>Set the assembly address. The address must be fully resolvable on the
 first pass so no external or forward references are permitted. ORG is not
-permitted within sections when outputting to object files. For the DECB
-target, each ORG directive after which output is generated will cause
-a new preamble to be output. ORG is only used to determine the addresses
-of symbols when the raw target is used.
+permitted within sections when outputting to object files. For target formats
+that include address information (decb, hex, srec, and ihex), an ORG 
+directive will re-start the address sequence within the output. When using
+the raw target format, ORG is used only to determine the addresses of symbols.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>REORG</term>
+<listitem>
+<para>
+Sets the assembly address to the value it had immediately prior to the
+previous ORG statement. It is used to continue assembly after some
+specification that required an additional ORG. This directive is primarily
+intended for MACRO-80c compatibility. Consider using alternatives in
+modern code.
 </para>
 </listitem>
 </varlistentry>
@@ -895,6 +1056,16 @@
 </varlistentry>
 
 <varlistentry>
+<term>IFPRAGMA <parameter>pragma</parameter></term>
+<listitem>
+<para>
+If <parameter>pragma</parameter> is in effect, the condition will be considered true.
+</para>
+</listitem>
+</varlistentry>
+
+
+<varlistentry>
 <term>IFNDEF <parameter>sym</parameter></term>
 <listitem>
 <para>If <parameter>sym</parameter> is not defined at this point in the assembly
@@ -1532,6 +1703,62 @@
 <para>Pragmas are not case sensitive.</para>
 
 <variablelist>
+
+<varlistentry>
+<term>6800compat</term>
+<listitem>
+
+<para>When in force, this pragma enables recognition of various
+compatibility instructions useful when assembling 6800 code.  These
+compatibility instructions are assembled into equivalent 6809 instructions. 
+This mode also includes several analogous instructions which are not
+strictly 6800 instructions but allow the similar style to be applied to 6809
+specific features.</para>
+
+<para>Technically, a compliant 6809 assembler must recognize these
+instructions by default since Motorola advertised the 6809 as being source
+compatible with the 6800.  However, most source code does not require this
+compatibility and LWASM itself did not support these instructions prior to
+version 4.11 so this mode is disabled by default.</para>
+
+</listitem>
+
+</varlistentry>
+
+<varlistentry>
+<term>6809</term>
+<listitem>
+<para>
+This pragma allows you to mark a section of code as 6809-only. In ths mode,
+the assembler will throw an error if any 6309 instructions are used.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>6309</term>
+<listitem>
+<para>
+This pragma enables the use of 6309 instructions and disables any 6809 specific
+instructions. It also changes the cycle count listing output (if selected)
+to display 6309 timings.
+</para>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>6809conv</term>
+<term>6309conv</term>
+<listitem>
+<para>
+These pragmas enable convenience instructions extending the 6809 and 6309
+instruction sets respectively. For more information, see 
+<xref linkend="convinst">.
+</para>
+</listitem>
+</varlistentry>
+
+
 <varlistentry>
 <term>index0tonone</term>
 <listitem>
@@ -1735,6 +1962,159 @@
 </listitem>
 </varlistentry>
 
+<varlistentry>
+<term>forwardrefmax</term>
+<listitem>
+
+<para>This pragma will disable forward reference optimization completely.
+Ordinarily, LWASM will attempt to select the shortest possible addressing
+mode for forward references.  However, in many source files, especially
+those not using the PCR relative addressing modes, this optimization is
+pointless since the assembler will almost certainly settle on a 16 bit
+offset or address.  If all variables in the direct page are defined before
+the main body of the code, the benefit of forward reference optimization
+almost certainly vanishes completely.  However, the cost of doing that
+optimization remains and can result in a very long assembly time.</para>
+
+<para>Enabling this pragma will cause all forward references to use the
+maximum offset or address size, much the same has EDTASM and other pure
+two pass assemblers do. The side effect is that all line lengths and
+symbol values are fully resolved after the initial parsing pass and the
+amount of work to resolve everything becomes almost nil.</para>
+
+<para>While this pragma can be applied selectively to sections of source
+code (use *PRAGMA if doing so and compatibility with other assemblers
+is desired), it is likely more useful when provided as a command line
+pragma.</para>
+
+<para>It should be noted that the presence or absence of this pragma
+will not change the correctness of the generated code unless cycle counts
+or byte counts are critical (which they usually are not). It also will
+not override the operand size override prefixes (&lt; and &gt;). It only
+applies when the assembler is left to guess what the operand size is.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>operandsizewarning</term>
+<listitem>
+
+<para>Enabling this pragma will cause LWASM to show a warning when it
+detects that a smaller addressing mode could be used for an instruction.
+This is particularly useful for finding places where long branches are used
+where short branches could be used instead. It will also show the warnings
+for indexing offsets (regardless of whether the operand size is
+forced).</para>
+
+<para>As of LWASM 4.16, no other checks are performed.</para>
+
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>qrts</term>
+<listitem>
+<para>
+
+Enables the use of the ?RTS branch target. ?RTS is implemented to maintain
+compatibility with the MACRO-80c assembler.  It works by searching backward
+in the code for an RTS instruction.  If none is found, it inverts the branch
+logic and inserts an RTS following the branch instruction.  Below you can
+see how a BMI (2B xx) has been assembled as a BPL *+1 (2A 01) to skip over an
+inserted RTS (39).
+</para>
+<programlisting>
+1D1E 7D1D1D            TST   WHICH1
+1D21 2A0139            BMI   ?RTS
+1D24 BD1D65            JSR   INV
+</programlisting>
+</listitem>
+</varlistentry>
+
+<varlistentry>
+<term>m80ext</term>
+<listitem>
+<para>
+
+This pragma (along with pragma qrts) enables some uncommon behaviors to
+accomodate The Micro Works MACRO-80c assembler from 1982.  This assembler
+was used by a number of notable TRS-80 Color Computer applications and the
+goal of this pragma is to allow them to build identical binaries from
+unmodified, vintage source code.
+</para>
+<para>
+
+In m80ext mode, the handling of the "END" pseudo-op changes when used inside
+an include file.  Instead of terminating all assembly, it merely stops
+processing of the current include file (this behavior matches the original
+Motorola 6809 assembler).  In addition, loading an ASCII value with a single
+quote (e.g., LDA #'N) is extended to 16-bit registers (e.g., LDD #'NO). 
+LWASM normally supports this via double quote and that is the proper use in
+modern code.  Finally, the FCC pseudo-op is extended to handle FCB-like
+behavior after the closing delimiter:
+</para>
+<programlisting>
+                       FCC "Greetings from 1982",13,0
+</programlisting>
+</listitem>
+</varlistentry>
+
+
+
+<varlistentry>
+<term>testmode</term>
+<listitem>
+<para>
+
+This pragma is intended for internal testing purposes. In testmode, the
+assembler searches for a specially-formatted comment starting with a
+semicolon followed by a period.  Immediately afterward are a list of hex
+bytes that the assembler is expected to generate.  Likewise, if the
+assembler is expected to throw an error or warning on a given line, you can
+check by specifying "E:" followed by the error number.  In this case the
+error is ignored and the assembler continues ignoring the line in question.
+
+</para>
+<programlisting>
+1D1E 7D1D1D            TST   WHICH1    ;.7d1d1d
+1D21 2A0139            BMI   ?RTS      ;.2a0139
+1D24 1D24              FDB   *         ;.1d24
+1D26                   xyz   INV       ;.E:32    (Error 32 is "Bad opcode")
+</programlisting>
+</listitem>
+</varlistentry>
+
+
+
+
+<varlistentry>
+<term>emuext</term>
+<listitem>
+<para>
+
+This pragma enables two instructions useful when running code in compatible
+emulators. Break breaks into the debugger. Log writes printf-style
+output to the debug window
+
+</para>
+<programlisting>
+      LOG           ; log output
+      FDB   FSTR    ; pointer to format string
+      FDB   PX1     ; 16 bit pointer to 16 bit value
+      FDB   PY1     ; 16 bit pointer to 8 bit value (see format string!)
+      FDB   PX2     ; 16 bit pointer to 16 bit value
+      FDB   PY2     ; 16 bit pointer to 8 bit value
+      ; execution continues here ...
+      RTS
+
+; format string
+FSTR  FCC   "%hu,%hhu - %hu,%hhu"
+      FCB   10,0
+</programlisting>
+</listitem>
+</varlistentry>
+
 </variablelist>
 
 <para>As a convenience, each input file has a pragma state stack. This
@@ -1757,6 +2137,74 @@
 
 </section>
 
+<section id="convinst">
+<title id="convinsttitle">Convenience Instructions</title>
+<para>
+
+Similar to the 6800 compatibility instructions (pragma 6800compat) these
+pragma 6809conv and pragma 6309conv enable convenience extensions to the
+6809 and 6309 instruction set.  Originally intended for compatibility with
+the MACRO-80c assembler, these have proven useful in large codebases that
+target both the 6809 and the 6309.
+</para>
+
+<para>
+
+The 6809 extensions are straightforward with the exception of "TSTD" which
+assembles as "STD -2,S".  A benefit of using these is they will "just work"
+and take on their 6309 equivalent when you enable 6309 assembly mode. 
+Supported instructions: ASRD, CLRD,   COMD,   LSLD,   LSRD,   NEGD,   TSTD.
+</para>
+<para>
+
+6309 extensions are based on common patterns described by Chris Burke and
+Darren Atkinson in their 6309 documentation and include the following
+instructions: ASRQ,   CLRQ,   COMQ,   LSLE,   LSLF,   LSLQ,   LSRQ,   NEGE,
+   NEGF,   NEGW,   NEGQ,   TSTQ.
+</para>
+</section>
+
+<section>
+<title>Cycle Counts</title>
+<para>
+
+The following options for displaying cycle counts in listings are provided.
+These options are enabled from pragmas on the command line or in the
+assembly files themselves.  For compatibility with other assemblers you can
+use the "OPT" keyword in addition to "PRAGMA."
+</para>
+
+<programlisting>
+opt c  - enable cycle counts: [8]
+opt cd - enable detailed cycle counts breaking down addressing modes: [5+3]
+opt ct - show a running subtotal of cycles
+opt cc - clear the running subtotal
+</programlisting>
+
+<para>
+
+The assembler supports both 6809 as well as native-mode 6309 cycle counts.
+In 6309 mode the counts are displayed in parenthesis instead of brackets. 
+In addition, some operations have a variable cycle count.  In this case a
+"+?" is displayed to alert the reader.  Sample output is shown below.
+</para>
+
+<programlisting>
+266f 7d25e2     (window.asm):00313 [7]     7       move   tst   putflg
+2672 2602       (window.asm):00314 [5]     12             bne   a@
+2674 1e13       (window.asm):00315 [8]     20             exg   x,u
+2676 0dd6       (window.asm):00316 [6]     26      a@     tst   is6309
+2678 2618       (window.asm):00317 [5]     31             bne   exit@
+                (window.asm):00318                        opt   6309
+267a 10860085   (window.asm):00319 (4)     35      b@     ldw   #133
+267e 113813     (window.asm):00320 (6+?)   41             tfm   x+,u+
+2681 30881b     (window.asm):00321 (4+1)   46             leax  27,x
+2684 33c81b     (window.asm):00322 (4+1)   51             leau  27,u
+2687 4a         (window.asm):00323 (1)     52             deca
+2688 26f0       (window.asm):00324 (5)     57             bne   b@
+</programlisting>
+</section>
+
 </chapter>
 
 <chapter>
@@ -1853,8 +2301,9 @@
 <term><option>-l LIBSPEC</option></term>
 <listitem>
 <para>
-Load a library using the library search path. LIBSPEC will have "lib" prepended
-and ".a" appended.
+Load a library using the library search path. If LIBSPEC is prefixed with a
+colon (":"), then LIBSPEC is the precise filename to be searched for in the
+library path. Otherwise, LIBSPEC will have "lib" prepended and ".a" appended.
 </para>
 </listitem>
 </varlistentry>
@@ -2114,6 +2563,25 @@
 </varlistentry>
 
 <varlistentry>
+<term>section <parameter>name</parameter> high <parameter>addr</parameter></term>
+<listitem><para>
+
+This causes the section <parameter>name</parameter> to load with its end
+address just below <parameter>addr</parameter>.  Subsequent sections are
+loaded at progressively lower addresses.  This may lead to inefficient file
+encoding for some targets.  As of this writing, it will also almost
+certainly do the wrong thing for a raw target.
+
+</para><para>
+
+This is useful for aligning a block of code with high memory.  As an
+example, if the total size of a section is $100 bytes and a high address of
+$FE00 is specified, the section will actually load at $FD00.
+
+</para></listitem>
+</varlistentry>
+
+<varlistentry>
 <term>section <parameter>name</parameter></term>
 <listitem><para>
 
--- a/docs/manual/c10.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Introduction</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="NEXT"
-TITLE="Output Formats"
-HREF="c18.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="index.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="c18.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="AEN10"
-></A
->Chapter 1. Introduction</H1
-><P
->The LW tool chain provides utilities for building binaries for MC6809 and
-HD6309 CPUs. The tool chain includes a cross-assembler and a cross-linker
-which support several styles of output.</P
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN13"
->1.1. History</A
-></H1
-><P
->For a long time, I have had an interest in creating an operating system for
-the Coco3. I finally started working on that project around the beginning of
-2006. I had a number of assemblers I could choose from. Eventually, I settled
-on one and started tinkering. After a while, I realized that assembler was not
-going to be sufficient due to lack of macros and issues with forward references.
-Then I tried another which handled forward references correctly but still did
-not support macros. I looked around at other assemblers and they all lacked
-one feature or another that I really wanted for creating my operating system.</P
-><P
->The solution seemed clear at that point. I am a fair programmer so I figured
-I could write an assembler that would do everything I wanted an assembler to
-do. Thus the LWASM probject was born. After more than two years of on and off
-work, version 1.0 of LWASM was released in October of 2008.</P
-><P
->As the aforementioned operating system project progressed further, it became
-clear that while assembling the whole project through a single file was doable,
-it was not practical. When I found myself playing some fancy games with macros
-in a bid to simulate sections, I realized I needed a means of assembling
-source files separately and linking them later. This spawned a major development
-effort to add an object file support to LWASM. It also spawned the LWLINK
-project to provide a means to actually link the files.</P
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="c18.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->LW Tool Chain</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Output Formats</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c1022.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,270 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Libraries and LWAR</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Format Specific Linking Notes"
+HREF="x1007.html"><LINK
+REL="NEXT"
+TITLE="Object Files"
+HREF="c1084.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x1007.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c1084.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="AEN1022"
+></A
+>Chapter 5. Libraries and LWAR</H1
+><P
+>LWTOOLS also includes a tool for managing libraries. These are analogous to
+the static libraries created with the "ar" tool on POSIX systems. Each library
+file contains one or more object files. The linker will treat the object
+files within a library as though they had been specified individually on
+the command line except when resolving external references. External references
+are looked up first within the object files within the library and then, if
+not found, the usual lookup based on the order the files are specified on
+the command line occurs.</P
+><P
+>The tool for creating these libary files is called LWAR.</P
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN1026"
+>5.1. Command Line Options</A
+></H1
+><P
+>The binary for LWAR is called "lwar". Note that the binary is in lower
+case. The options lwar understands are listed below. For archive manipulation
+options, the first non-option argument is the name of the archive. All other
+non-option arguments are the names of files to operate on.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><CODE
+CLASS="OPTION"
+>--add</CODE
+>, <CODE
+CLASS="OPTION"
+>-a</CODE
+></DT
+><DD
+><P
+>This option specifies that an archive is going to have files added to it.
+If the archive does not already exist, it is created. New files are added
+to the end of the archive.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--create</CODE
+>, <CODE
+CLASS="OPTION"
+>-c</CODE
+></DT
+><DD
+><P
+>This option specifies that an archive is going to be created and have files
+added to it. If the archive already exists, it is truncated.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--merge</CODE
+>, <CODE
+CLASS="OPTION"
+>-m</CODE
+></DT
+><DD
+><P
+>If specified, any files specified to be added to an archive will be checked
+to see if they are archives themselves. If so, their constituent members are
+added to the archive. This is useful for avoiding archives containing archives.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--list</CODE
+>, <CODE
+CLASS="OPTION"
+>-l</CODE
+></DT
+><DD
+><P
+>This will display a list of the files contained in the archive.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--debug</CODE
+>, <CODE
+CLASS="OPTION"
+>-d</CODE
+></DT
+><DD
+><P
+>This option increases the debugging level. It is only useful for LWTOOLS
+developers.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--help</CODE
+>, <CODE
+CLASS="OPTION"
+>-?</CODE
+></DT
+><DD
+><P
+>This provides a listing of command line options and a brief description
+of each.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--usage</CODE
+></DT
+><DD
+><P
+>This will display a usage summary
+of each command line option.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--version</CODE
+>, <CODE
+CLASS="OPTION"
+>-V</CODE
+></DT
+><DD
+><P
+>This will display the version of LWLINK.
+of each.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x1007.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c1084.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Format Specific Linking Notes</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Object Files</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c1084.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,376 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Object Files</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Libraries and LWAR"
+HREF="c1022.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c1022.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+>&nbsp;</TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="OBJCHAP"
+></A
+>Chapter 6. Object Files</H1
+><P
+>LWTOOLS uses a proprietary object file format. It is proprietary in the sense
+that it is specific to LWTOOLS, not that it is a hidden format. It would be
+hard to keep it hidden in an open source tool chain anyway. This chapter
+documents the object file format.</P
+><P
+>An object file consists of a series of sections each of which contains a
+list of exported symbols, a list of incomplete references, and a list of
+"local" symbols which may be used in calculating incomplete references. Each
+section will obviously also contain the object code.</P
+><P
+>Exported symbols must be completely resolved to an address within the
+section it is exported from. That is, an exported symbol must be a constant
+rather than defined in terms of other symbols.</P
+><P
+>Each object file starts with a magic number and version number. The magic
+number is the string "LWOBJ16" for this 16 bit object file format. The only
+defined version number is currently 0. Thus, the first 8 bytes of the object
+file are <FONT
+COLOR="RED"
+>4C574F424A313600</FONT
+></P
+><P
+>Each section has the following items in order:</P
+><P
+></P
+><UL
+><LI
+><P
+>section name</P
+></LI
+><LI
+><P
+>flags</P
+></LI
+><LI
+><P
+>list of local symbols (and addresses within the section)</P
+></LI
+><LI
+><P
+>list of exported symbols (and addresses within the section)</P
+></LI
+><LI
+><P
+>list of incomplete references along with the expressions to calculate them</P
+></LI
+><LI
+><P
+>the actual object code (for non-BSS sections)</P
+></LI
+></UL
+><P
+>The section starts with the name of the section with a NUL termination
+followed by a series of flag bytes terminated by NUL. There are only two
+flag bytes defined. A NUL (0) indicates no more flags and a value of 1
+indicates the section is a BSS section. For a BSS section, no actual
+code is included in the object file.</P
+><P
+>Either a NULL section name or end of file indicate the presence of no more
+sections.</P
+><P
+>Each entry in the exported and local symbols table consists of the symbol
+(NUL terminated) followed by two bytes which contain the value in big endian
+order. The end of a symbol table is indicated by a NULL symbol name.</P
+><P
+>Each entry in the incomplete references table consists of an expression
+followed by a 16 bit offset where the reference goes. Expressions are
+defined as a series of terms up to an "end of expression" term. Each term
+consists of a single byte which identifies the type of term (see below)
+followed by any data required by the term. Then end of the list is flagged
+by a NULL expression (only an end of expression term).</P
+><DIV
+CLASS="TABLE"
+><A
+NAME="AEN1109"
+></A
+><P
+><B
+>Table 6-1. Object File Term Types</B
+></P
+><TABLE
+BORDER="1"
+FRAME="border"
+CLASS="CALSTABLE"
+><COL><COL><THEAD
+><TR
+><TH
+>TERMTYPE</TH
+><TH
+>Meaning</TH
+></TR
+></THEAD
+><TBODY
+><TR
+><TD
+>00</TD
+><TD
+>end of expression</TD
+></TR
+><TR
+><TD
+>01</TD
+><TD
+>integer (16 bit in big endian order follows)</TD
+></TR
+><TR
+><TD
+>02</TD
+><TD
+>	external symbol reference (NUL terminated symbol name follows)</TD
+></TR
+><TR
+><TD
+>03</TD
+><TD
+>local symbol reference (NUL terminated symbol name follows)</TD
+></TR
+><TR
+><TD
+>04</TD
+><TD
+>operator (1 byte operator number)</TD
+></TR
+><TR
+><TD
+>05</TD
+><TD
+>section base address reference</TD
+></TR
+><TR
+><TD
+>FF</TD
+><TD
+>This term will set flags for the expression. Each one of these terms will set a single flag. All of them should be specified first in an expression. If they are not, the behaviour is undefined. The byte following is the flag. Flag 01 indicates an 8 bit relocation. Flag 02 indicates a zero-width relocation (see the EXTDEP pseudo op in LWASM).</TD
+></TR
+></TBODY
+></TABLE
+></DIV
+><P
+>External references are resolved using other object files while local
+references are resolved using the local symbol table(s) from this file. This
+allows local symbols that are not exported to have the same names as
+exported symbols or external references.</P
+><DIV
+CLASS="TABLE"
+><A
+NAME="AEN1139"
+></A
+><P
+><B
+>Table 6-2. Object File Operator Numbers</B
+></P
+><TABLE
+BORDER="1"
+FRAME="border"
+CLASS="CALSTABLE"
+><COL><COL><THEAD
+><TR
+><TH
+>Number</TH
+><TH
+>Operator</TH
+></TR
+></THEAD
+><TBODY
+><TR
+><TD
+>01</TD
+><TD
+>addition (+)</TD
+></TR
+><TR
+><TD
+>02</TD
+><TD
+>subtraction (-)</TD
+></TR
+><TR
+><TD
+>03</TD
+><TD
+>multiplication (*)</TD
+></TR
+><TR
+><TD
+>04</TD
+><TD
+>division (/)</TD
+></TR
+><TR
+><TD
+>05</TD
+><TD
+>modulus (%)</TD
+></TR
+><TR
+><TD
+>06</TD
+><TD
+>integer division (\) (same as division)</TD
+></TR
+><TR
+><TD
+>07</TD
+><TD
+>bitwise and</TD
+></TR
+><TR
+><TD
+>08</TD
+><TD
+>bitwise or</TD
+></TR
+><TR
+><TD
+>09</TD
+><TD
+>bitwise xor</TD
+></TR
+><TR
+><TD
+>0A</TD
+><TD
+>boolean and</TD
+></TR
+><TR
+><TD
+>0B</TD
+><TD
+>boolean or</TD
+></TR
+><TR
+><TD
+>0C</TD
+><TD
+>unary negation, 2's complement (-)</TD
+></TR
+><TR
+><TD
+>0D</TD
+><TD
+>unary 1's complement (^)</TD
+></TR
+></TBODY
+></TABLE
+></DIV
+><P
+>An expression is represented in a postfix manner with both operands for
+binary operators preceding the operator and the single operand for unary
+operators preceding the operator.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c1022.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Libraries and LWAR</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>&nbsp;</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c13.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Introduction</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="NEXT"
+TITLE="Output Formats"
+HREF="c21.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c21.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="AEN13"
+></A
+>Chapter 1. Introduction</H1
+><P
+>The LW tool chain provides utilities for building binaries for MC6809 and
+HD6309 CPUs. The tool chain includes a cross-assembler and a cross-linker
+which support several styles of output.</P
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN16"
+>1.1. History</A
+></H1
+><P
+>For a long time, I have had an interest in creating an operating system for
+the Coco3. I finally started working on that project around the beginning of
+2006. I had a number of assemblers I could choose from. Eventually, I settled
+on one and started tinkering. After a while, I realized that assembler was not
+going to be sufficient due to lack of macros and issues with forward references.
+Then I tried another which handled forward references correctly but still did
+not support macros. I looked around at other assemblers and they all lacked
+one feature or another that I really wanted for creating my operating system.</P
+><P
+>The solution seemed clear at that point. I am a fair programmer so I figured
+I could write an assembler that would do everything I wanted an assembler to
+do. Thus the LWASM probject was born. After more than two years of on and off
+work, version 1.0 of LWASM was released in October of 2008.</P
+><P
+>As the aforementioned operating system project progressed further, it became
+clear that while assembling the whole project through a single file was doable,
+it was not practical. When I found myself playing some fancy games with macros
+in a bid to simulate sections, I realized I needed a means of assembling
+source files separately and linking them later. This spawned a major development
+effort to add an object file support to LWASM. It also spawned the LWLINK
+project to provide a means to actually link the files.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>LW Tool Chain</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Output Formats</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/c18.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Output Formats</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="Introduction"
-HREF="c10.html"><LINK
-REL="NEXT"
-TITLE="DECB Binaries"
-HREF="x24.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="c10.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x24.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="AEN18"
-></A
->Chapter 2. Output Formats</H1
-><P
->The LW tool chain supports multiple output formats. Each format has its
-advantages and disadvantages. Each format is described below.</P
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN21"
->2.1. Raw Binaries</A
-></H1
-><P
->A raw binary is simply a string of bytes. There are no headers or other
-niceties. Both LWLINK and LWASM support generating raw binaries. ORG directives
-in the source code only serve to set the addresses that will be used for
-symbols but otherwise have no direct impact on the resulting binary.</P
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="c10.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x24.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Introduction</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->DECB Binaries</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c21.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,153 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Output Formats</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Introduction"
+HREF="c13.html"><LINK
+REL="NEXT"
+TITLE="DECB Binaries"
+HREF="x27.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c13.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x27.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="AEN21"
+></A
+>Chapter 2. Output Formats</H1
+><P
+>The LW tool chain supports multiple output formats. Each format has its
+advantages and disadvantages. Each format is described below.</P
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN24"
+>2.1. Raw Binaries</A
+></H1
+><P
+>A raw binary is simply a string of bytes. There are no headers or other
+niceties. Both LWLINK and LWASM support generating raw binaries. ORG directives
+in the source code only serve to set the addresses that will be used for
+symbols but otherwise have no direct impact on the resulting binary.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c13.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x27.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Introduction</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>DECB Binaries</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/c45.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,395 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->LWASM</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="Object Files"
-HREF="x37.html"><LINK
-REL="NEXT"
-TITLE="Dialects"
-HREF="x170.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x37.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x170.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="AEN45"
-></A
->Chapter 3. LWASM</H1
-><P
->The LWTOOLS assembler is called LWASM. This chapter documents the various
-features of the assembler. It is not, however, a tutorial on 6x09 assembly
-language programming.</P
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN48"
->3.1. Command Line Options</A
-></H1
-><P
->The binary for LWASM is called "lwasm". Note that the binary is in lower
-case. lwasm takes the following command line arguments.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
-><CODE
-CLASS="OPTION"
->--6309</CODE
->, <CODE
-CLASS="OPTION"
->-3</CODE
-></DT
-><DD
-><P
->This will cause the assembler to accept the additional instructions available
-on the 6309 processor. This is the default mode; this option is provided for
-completeness and to override preset command arguments.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--6809</CODE
->, <CODE
-CLASS="OPTION"
->-9</CODE
-></DT
-><DD
-><P
->This will cause the assembler to reject instructions that are only available
-on the 6309 processor.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--decb</CODE
->, <CODE
-CLASS="OPTION"
->-b</CODE
-></DT
-><DD
-><P
->Select the DECB output format target. Equivalent to <CODE
-CLASS="OPTION"
->--format=decb</CODE
->.</P
-><P
->While this is the default output format currently, it is not safe to rely
-on that fact. Future versions may have different defaults. It is also trivial
-to modify the source code to change the default. Thus, it is recommended to specify
-this option if you need DECB output.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--format=type</CODE
->, <CODE
-CLASS="OPTION"
->-f type</CODE
-></DT
-><DD
-><P
->Select the output format. Valid values are <CODE
-CLASS="OPTION"
->obj</CODE
-> for the
-object file target, <CODE
-CLASS="OPTION"
->decb</CODE
-> for the DECB LOADM format,
-<CODE
-CLASS="OPTION"
->os9</CODE
-> for creating OS9 modules, and <CODE
-CLASS="OPTION"
->raw</CODE
-> for
-a raw binary.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--list[=file]</CODE
->, <CODE
-CLASS="OPTION"
->-l[file]</CODE
-></DT
-><DD
-><P
->Cause LWASM to generate a listing. If <CODE
-CLASS="OPTION"
->file</CODE
-> is specified,
-the listing will go to that file. Otherwise it will go to the standard output
-stream. By default, no listing is generated. Unless <CODE
-CLASS="OPTION"
->--symbols</CODE
->
-is specified, the list will not include the symbol table.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--symbols</CODE
->, <CODE
-CLASS="OPTION"
->-s</CODE
-></DT
-><DD
-><P
->Causes LWASM to generate a list of symbols when generating a listing.
-It has no effect unless a listing is being generated.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--obj</CODE
-></DT
-><DD
-><P
->Select the proprietary object file format as the output target.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--output=FILE</CODE
->, <CODE
-CLASS="OPTION"
->-o FILE</CODE
-></DT
-><DD
-><P
->This option specifies the name of the output file. If not specified, the
-default is <CODE
-CLASS="OPTION"
->a.out</CODE
->.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--pragma=pragma</CODE
->, <CODE
-CLASS="OPTION"
->-p pragma</CODE
-></DT
-><DD
-><P
->Specify assembler pragmas. Multiple pragmas are separated by commas. The
-pragmas accepted are the same as for the PRAGMA assembler directive described
-below.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--raw</CODE
->, <CODE
-CLASS="OPTION"
->-r</CODE
-></DT
-><DD
-><P
->Select raw binary as the output target.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--includedir=path</CODE
->, <CODE
-CLASS="OPTION"
->-I path</CODE
-></DT
-><DD
-><P
->Add <CODE
-CLASS="OPTION"
->path</CODE
-> to the end of the include path.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--define=SYM[=VAL]</CODE
->, <CODE
-CLASS="OPTION"
->-D SYM[=VAL]</CODE
-></DT
-><DD
-><P
->Pre-defines the symbol SYM as either the specified VAL. If VAL is omitted,
-the symbol is defined as 1.  The symbol will be defined as though it were
-defined using the SET directive in the assembly source.  That means it can
-be overridden by a SET directive within the source code.  Attempting to
-redefine SYM using EQU will result in a multiply defined symbol error.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--help</CODE
->, <CODE
-CLASS="OPTION"
->-?</CODE
-></DT
-><DD
-><P
->Present a help screen describing the command line options.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--usage</CODE
-></DT
-><DD
-><P
->Provide a summary of the command line options.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--version</CODE
->, <CODE
-CLASS="OPTION"
->-V</CODE
-></DT
-><DD
-><P
->Display the software version.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--debug</CODE
->, <CODE
-CLASS="OPTION"
->-d</CODE
-></DT
-><DD
-><P
->Increase the debugging level. Only really useful to people hacking on the
-LWASM source code itself.</P
-></DD
-></DL
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x37.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x170.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Object Files</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Dialects</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c62.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,490 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>LWASM</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Object Files"
+HREF="x54.html"><LINK
+REL="NEXT"
+TITLE="Dialects"
+HREF="x229.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x229.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="AEN62"
+></A
+>Chapter 3. LWASM</H1
+><P
+>The LWTOOLS assembler is called LWASM. This chapter documents the various
+features of the assembler. It is not, however, a tutorial on 6x09 assembly
+language programming.</P
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN65"
+>3.1. Command Line Options</A
+></H1
+><P
+>The binary for LWASM is called "lwasm". Note that the binary is in lower
+case. lwasm takes the following command line arguments.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><CODE
+CLASS="OPTION"
+>--6309</CODE
+>, <CODE
+CLASS="OPTION"
+>-3</CODE
+></DT
+><DD
+><P
+>This will cause the assembler to accept the additional instructions available
+on the 6309 processor. This is the default mode; this option is provided for
+completeness and to override preset command arguments.</P
+><P
+>This option is the same as if the first line of the source code is "PRAGMA 6309".</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--6800compat</CODE
+></DT
+><DD
+><P
+>This is equivalent to <CODE
+CLASS="OPTION"
+>--pragma=6800compat</CODE
+>.</P
+><P
+>This will enable recognition of 6800 compatibility instructions.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--6809</CODE
+>, <CODE
+CLASS="OPTION"
+>-9</CODE
+></DT
+><DD
+><P
+>This will cause the assembler to reject instructions that are only available
+on the 6309 processor. This actually has the effect of starting the assembler
+as though the first line of the source is "PRAGMA 6809".</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--decb</CODE
+>, <CODE
+CLASS="OPTION"
+>-b</CODE
+></DT
+><DD
+><P
+>Select the DECB output format target. Equivalent to <CODE
+CLASS="OPTION"
+>--format=decb</CODE
+>.</P
+><P
+>While this is the default output format currently, it is not safe to rely
+on that fact. Future versions may have different defaults. It is also trivial
+to modify the source code to change the default. Thus, it is recommended to specify
+this option if you need DECB output.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--format=type</CODE
+>, <CODE
+CLASS="OPTION"
+>-f type</CODE
+></DT
+><DD
+><P
+>Select the output format. Valid values are <CODE
+CLASS="OPTION"
+>obj</CODE
+> for the
+object file target, <CODE
+CLASS="OPTION"
+>decb</CODE
+> for the DECB LOADM format,
+<CODE
+CLASS="OPTION"
+>os9</CODE
+> for creating OS9 modules, <CODE
+CLASS="OPTION"
+>raw</CODE
+> for
+a raw binary, <CODE
+CLASS="OPTION"
+>hex</CODE
+> for ASCII hexadecminal format, 
+<CODE
+CLASS="OPTION"
+>srec</CODE
+> for Motorola S-Record format, and <CODE
+CLASS="OPTION"
+>ihex</CODE
+>
+ for Intel Hex format.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--list[=file]</CODE
+>, <CODE
+CLASS="OPTION"
+>-l[file]</CODE
+></DT
+><DD
+><P
+>Cause LWASM to generate a listing. If <CODE
+CLASS="OPTION"
+>file</CODE
+> is specified,
+the listing will go to that file. Otherwise it will go to the standard output
+stream. By default, no listing is generated. Unless <CODE
+CLASS="OPTION"
+>--symbols</CODE
+>
+is specified, the list will not include the symbol table.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--symbol-dump[=file]</CODE
+></DT
+><DD
+><P
+>Cause LWASM to output the global symbol table in assembly source format. If
+<CODE
+CLASS="OPTION"
+>file</CODE
+> is specified, the table output will go to the specified
+file. Otherwise, it will go to the standard output stream. Local symbols will
+not be included. Incomplete symbols will be defined to zero with a comment
+indicating incompleteness. Symbols defined with SET will also be listed using
+SET in the symbol dump. However, if the symbol is defined multiple times, the
+order of the definitions in the dump file is undefined.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--symbols</CODE
+>, <CODE
+CLASS="OPTION"
+>-s</CODE
+></DT
+><DD
+><P
+>Causes LWASM to generate a list of symbols when generating a listing.
+It has no effect unless a listing is being generated.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--symbols-nolocals</CODE
+></DT
+><DD
+><P
+>Behaves just like <CODE
+CLASS="OPTION"
+>--symbols</CODE
+> but with local labels omitted.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--map=FILE</CODE
+></DT
+><DD
+><P
+>&#13;This option generates a map file which can be used by debuggers and monitors to provide symbol information. A map file may be created independent of a listing file. (Patches are pending for MAME and exec09.)&#13;</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--obj</CODE
+></DT
+><DD
+><P
+>Select the proprietary object file format as the output target.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--output=FILE</CODE
+>, <CODE
+CLASS="OPTION"
+>-o FILE</CODE
+></DT
+><DD
+><P
+>This option specifies the name of the output file. If not specified, the
+default is <CODE
+CLASS="OPTION"
+>a.out</CODE
+>.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--no-output</CODE
+></DT
+><DD
+><P
+>Do assembly as usual but suppress generation of the output file.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--pragma=pragma</CODE
+>, <CODE
+CLASS="OPTION"
+>-p pragma</CODE
+></DT
+><DD
+><P
+>Specify assembler pragmas. Multiple pragmas are separated by commas. The
+pragmas accepted are the same as for the PRAGMA assembler directive described
+below.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--raw</CODE
+>, <CODE
+CLASS="OPTION"
+>-r</CODE
+></DT
+><DD
+><P
+>Select raw binary as the output target.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--includedir=path</CODE
+>, <CODE
+CLASS="OPTION"
+>-I path</CODE
+></DT
+><DD
+><P
+>Add <CODE
+CLASS="OPTION"
+>path</CODE
+> to the end of the include path.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--define=SYM[=VAL]</CODE
+>, <CODE
+CLASS="OPTION"
+>-D SYM[=VAL]</CODE
+></DT
+><DD
+><P
+>Pre-defines the symbol SYM as either the specified VAL. If VAL is omitted,
+the symbol is defined as 1.  The symbol will be defined as though it were
+defined using the SET directive in the assembly source.  That means it can
+be overridden by a SET directive within the source code.  Attempting to
+redefine SYM using EQU will result in a multiply defined symbol error.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>-t WIDTH</CODE
+>, <CODE
+CLASS="OPTION"
+>--tabs=WIDTH</CODE
+></DT
+><DD
+><P
+>Specifies the handling of tabs in listing files. <CODE
+CLASS="OPTION"
+>--tabs=0</CODE
+>
+disables tab expansion. <CODE
+CLASS="OPTION"
+>--tabs=8</CODE
+> is the default setting.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--help</CODE
+>, <CODE
+CLASS="OPTION"
+>-?</CODE
+></DT
+><DD
+><P
+>Present a help screen describing the command line options.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--usage</CODE
+></DT
+><DD
+><P
+>Provide a summary of the command line options.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--version</CODE
+>, <CODE
+CLASS="OPTION"
+>-V</CODE
+></DT
+><DD
+><P
+>Display the software version.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--debug</CODE
+>, <CODE
+CLASS="OPTION"
+>-d</CODE
+></DT
+><DD
+><P
+>Increase the debugging level. Only really useful to people hacking on the
+LWASM source code itself.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x54.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x229.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Object Files</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Dialects</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/c693.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,336 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->LWLINK</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="Assembler Modes and Pragmas"
-HREF="x599.html"><LINK
-REL="NEXT"
-TITLE="Linker Operation"
-HREF="x793.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x599.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x793.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="AEN693"
-></A
->Chapter 4. LWLINK</H1
-><P
->The LWTOOLS linker is called LWLINK. This chapter documents the various features
-of the linker.</P
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN696"
->4.1. Command Line Options</A
-></H1
-><P
->The binary for LWLINK is called "lwlink". Note that the binary is in lower
-case. lwlink takes the following command line arguments.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
-><CODE
-CLASS="OPTION"
->--decb</CODE
->, <CODE
-CLASS="OPTION"
->-b</CODE
-></DT
-><DD
-><P
->Selects the DECB output format target. This is equivalent to <CODE
-CLASS="OPTION"
->--format=decb</CODE
-></P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--output=FILE</CODE
->, <CODE
-CLASS="OPTION"
->-o FILE</CODE
-></DT
-><DD
-><P
->This option specifies the name of the output file. If not specified, the
-default is <CODE
-CLASS="OPTION"
->a.out</CODE
->.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--format=TYPE</CODE
->, <CODE
-CLASS="OPTION"
->-f TYPE</CODE
-></DT
-><DD
-><P
->This option specifies the output format. Valid values are <CODE
-CLASS="OPTION"
->decb</CODE
->
-and <CODE
-CLASS="OPTION"
->raw</CODE
-></P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--raw</CODE
->, <CODE
-CLASS="OPTION"
->-r</CODE
-></DT
-><DD
-><P
->This option specifies the raw output format.
-It is equivalent to <CODE
-CLASS="OPTION"
->--format=raw</CODE
->
-and <CODE
-CLASS="OPTION"
->-f raw</CODE
-></P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--script=FILE</CODE
->, <CODE
-CLASS="OPTION"
->-s</CODE
-></DT
-><DD
-><P
->This option allows specifying a linking script to override the linker's
-built in defaults.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--section-base=SECT=BASE</CODE
-></DT
-><DD
-><P
->Cause section SECT to load at base address BASE. This will be prepended
-to the built-in link script. It is ignored if a link script is provided.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--map=FILE</CODE
->, <CODE
-CLASS="OPTION"
->-m FILE</CODE
-></DT
-><DD
-><P
->This will output a description of the link result to FILE.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--library=LIBSPEC</CODE
->, <CODE
-CLASS="OPTION"
->-l LIBSPEC</CODE
-></DT
-><DD
-><P
->Load a library using the library search path. LIBSPEC will have "lib" prepended
-and ".a" appended.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--library-path=DIR</CODE
->, <CODE
-CLASS="OPTION"
->-L DIR</CODE
-></DT
-><DD
-><P
->Add DIR to the library search path.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--debug</CODE
->, <CODE
-CLASS="OPTION"
->-d</CODE
-></DT
-><DD
-><P
->This option increases the debugging level. It is only useful for LWTOOLS
-developers.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--help</CODE
->, <CODE
-CLASS="OPTION"
->-?</CODE
-></DT
-><DD
-><P
->This provides a listing of command line options and a brief description
-of each.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--usage</CODE
-></DT
-><DD
-><P
->This will display a usage summary
-of each command line option.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--version</CODE
->, <CODE
-CLASS="OPTION"
->-V</CODE
-></DT
-><DD
-><P
->This will display the version of LWLINK.</P
-></DD
-></DL
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x599.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x793.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Assembler Modes and Pragmas</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Linker Operation</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/c827.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,337 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>LWLINK</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="PREVIOUS"
+TITLE="Cycle Counts"
+HREF="x821.html"><LINK
+REL="NEXT"
+TITLE="Linker Operation"
+HREF="x927.html"></HEAD
+><BODY
+CLASS="CHAPTER"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x821.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+></TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x927.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="CHAPTER"
+><H1
+><A
+NAME="AEN827"
+></A
+>Chapter 4. LWLINK</H1
+><P
+>The LWTOOLS linker is called LWLINK. This chapter documents the various features
+of the linker.</P
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN830"
+>4.1. Command Line Options</A
+></H1
+><P
+>The binary for LWLINK is called "lwlink". Note that the binary is in lower
+case. lwlink takes the following command line arguments.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><CODE
+CLASS="OPTION"
+>--decb</CODE
+>, <CODE
+CLASS="OPTION"
+>-b</CODE
+></DT
+><DD
+><P
+>Selects the DECB output format target. This is equivalent to <CODE
+CLASS="OPTION"
+>--format=decb</CODE
+></P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--output=FILE</CODE
+>, <CODE
+CLASS="OPTION"
+>-o FILE</CODE
+></DT
+><DD
+><P
+>This option specifies the name of the output file. If not specified, the
+default is <CODE
+CLASS="OPTION"
+>a.out</CODE
+>.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--format=TYPE</CODE
+>, <CODE
+CLASS="OPTION"
+>-f TYPE</CODE
+></DT
+><DD
+><P
+>This option specifies the output format. Valid values are <CODE
+CLASS="OPTION"
+>decb</CODE
+>
+and <CODE
+CLASS="OPTION"
+>raw</CODE
+></P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--raw</CODE
+>, <CODE
+CLASS="OPTION"
+>-r</CODE
+></DT
+><DD
+><P
+>This option specifies the raw output format.
+It is equivalent to <CODE
+CLASS="OPTION"
+>--format=raw</CODE
+>
+and <CODE
+CLASS="OPTION"
+>-f raw</CODE
+></P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--script=FILE</CODE
+>, <CODE
+CLASS="OPTION"
+>-s</CODE
+></DT
+><DD
+><P
+>This option allows specifying a linking script to override the linker's
+built in defaults.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--section-base=SECT=BASE</CODE
+></DT
+><DD
+><P
+>Cause section SECT to load at base address BASE. This will be prepended
+to the built-in link script. It is ignored if a link script is provided.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--map=FILE</CODE
+>, <CODE
+CLASS="OPTION"
+>-m FILE</CODE
+></DT
+><DD
+><P
+>This will output a description of the link result to FILE.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--library=LIBSPEC</CODE
+>, <CODE
+CLASS="OPTION"
+>-l LIBSPEC</CODE
+></DT
+><DD
+><P
+>Load a library using the library search path. If LIBSPEC is prefixed with a
+colon (":"), then LIBSPEC is the precise filename to be searched for in the
+library path. Otherwise, LIBSPEC will have "lib" prepended and ".a" appended.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--library-path=DIR</CODE
+>, <CODE
+CLASS="OPTION"
+>-L DIR</CODE
+></DT
+><DD
+><P
+>Add DIR to the library search path.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--debug</CODE
+>, <CODE
+CLASS="OPTION"
+>-d</CODE
+></DT
+><DD
+><P
+>This option increases the debugging level. It is only useful for LWTOOLS
+developers.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--help</CODE
+>, <CODE
+CLASS="OPTION"
+>-?</CODE
+></DT
+><DD
+><P
+>This provides a listing of command line options and a brief description
+of each.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--usage</CODE
+></DT
+><DD
+><P
+>This will display a usage summary
+of each command line option.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--version</CODE
+>, <CODE
+CLASS="OPTION"
+>-V</CODE
+></DT
+><DD
+><P
+>This will display the version of LWLINK.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x821.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x927.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Cycle Counts</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+>&nbsp;</TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Linker Operation</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/c879.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Libraries and LWAR</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="Format Specific Linking Notes"
-HREF="x864.html"><LINK
-REL="NEXT"
-TITLE="Object Files"
-HREF="c941.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x864.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="c941.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="AEN879"
-></A
->Chapter 5. Libraries and LWAR</H1
-><P
->LWTOOLS also includes a tool for managing libraries. These are analogous to
-the static libraries created with the "ar" tool on POSIX systems. Each library
-file contains one or more object files. The linker will treat the object
-files within a library as though they had been specified individually on
-the command line except when resolving external references. External references
-are looked up first within the object files within the library and then, if
-not found, the usual lookup based on the order the files are specified on
-the command line occurs.</P
-><P
->The tool for creating these libary files is called LWAR.</P
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN883"
->5.1. Command Line Options</A
-></H1
-><P
->The binary for LWAR is called "lwar". Note that the binary is in lower
-case. The options lwar understands are listed below. For archive manipulation
-options, the first non-option argument is the name of the archive. All other
-non-option arguments are the names of files to operate on.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
-><CODE
-CLASS="OPTION"
->--add</CODE
->, <CODE
-CLASS="OPTION"
->-a</CODE
-></DT
-><DD
-><P
->This option specifies that an archive is going to have files added to it.
-If the archive does not already exist, it is created. New files are added
-to the end of the archive.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--create</CODE
->, <CODE
-CLASS="OPTION"
->-c</CODE
-></DT
-><DD
-><P
->This option specifies that an archive is going to be created and have files
-added to it. If the archive already exists, it is truncated.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--merge</CODE
->, <CODE
-CLASS="OPTION"
->-m</CODE
-></DT
-><DD
-><P
->If specified, any files specified to be added to an archive will be checked
-to see if they are archives themselves. If so, their constituent members are
-added to the archive. This is useful for avoiding archives containing archives.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--list</CODE
->, <CODE
-CLASS="OPTION"
->-l</CODE
-></DT
-><DD
-><P
->This will display a list of the files contained in the archive.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--debug</CODE
->, <CODE
-CLASS="OPTION"
->-d</CODE
-></DT
-><DD
-><P
->This option increases the debugging level. It is only useful for LWTOOLS
-developers.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--help</CODE
->, <CODE
-CLASS="OPTION"
->-?</CODE
-></DT
-><DD
-><P
->This provides a listing of command line options and a brief description
-of each.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--usage</CODE
-></DT
-><DD
-><P
->This will display a usage summary
-of each command line option.</P
-></DD
-><DT
-><CODE
-CLASS="OPTION"
->--version</CODE
->, <CODE
-CLASS="OPTION"
->-V</CODE
-></DT
-><DD
-><P
->This will display the version of LWLINK.
-of each.</P
-></DD
-></DL
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x864.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="c941.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Format Specific Linking Notes</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Object Files</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/c941.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,376 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Object Files</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="PREVIOUS"
-TITLE="Libraries and LWAR"
-HREF="c879.html"></HEAD
-><BODY
-CLASS="CHAPTER"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="c879.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
-></TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
->&nbsp;</TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="CHAPTER"
-><H1
-><A
-NAME="OBJCHAP"
-></A
->Chapter 6. Object Files</H1
-><P
->LWTOOLS uses a proprietary object file format. It is proprietary in the sense
-that it is specific to LWTOOLS, not that it is a hidden format. It would be
-hard to keep it hidden in an open source tool chain anyway. This chapter
-documents the object file format.</P
-><P
->An object file consists of a series of sections each of which contains a
-list of exported symbols, a list of incomplete references, and a list of
-"local" symbols which may be used in calculating incomplete references. Each
-section will obviously also contain the object code.</P
-><P
->Exported symbols must be completely resolved to an address within the
-section it is exported from. That is, an exported symbol must be a constant
-rather than defined in terms of other symbols.</P
-><P
->Each object file starts with a magic number and version number. The magic
-number is the string "LWOBJ16" for this 16 bit object file format. The only
-defined version number is currently 0. Thus, the first 8 bytes of the object
-file are <FONT
-COLOR="RED"
->4C574F424A313600</FONT
-></P
-><P
->Each section has the following items in order:</P
-><P
-></P
-><UL
-><LI
-><P
->section name</P
-></LI
-><LI
-><P
->flags</P
-></LI
-><LI
-><P
->list of local symbols (and addresses within the section)</P
-></LI
-><LI
-><P
->list of exported symbols (and addresses within the section)</P
-></LI
-><LI
-><P
->list of incomplete references along with the expressions to calculate them</P
-></LI
-><LI
-><P
->the actual object code (for non-BSS sections)</P
-></LI
-></UL
-><P
->The section starts with the name of the section with a NUL termination
-followed by a series of flag bytes terminated by NUL. There are only two
-flag bytes defined. A NUL (0) indicates no more flags and a value of 1
-indicates the section is a BSS section. For a BSS section, no actual
-code is included in the object file.</P
-><P
->Either a NULL section name or end of file indicate the presence of no more
-sections.</P
-><P
->Each entry in the exported and local symbols table consists of the symbol
-(NUL terminated) followed by two bytes which contain the value in big endian
-order. The end of a symbol table is indicated by a NULL symbol name.</P
-><P
->Each entry in the incomplete references table consists of an expression
-followed by a 16 bit offset where the reference goes. Expressions are
-defined as a series of terms up to an "end of expression" term. Each term
-consists of a single byte which identifies the type of term (see below)
-followed by any data required by the term. Then end of the list is flagged
-by a NULL expression (only an end of expression term).</P
-><DIV
-CLASS="TABLE"
-><A
-NAME="AEN966"
-></A
-><P
-><B
->Table 6-1. Object File Term Types</B
-></P
-><TABLE
-BORDER="1"
-FRAME="border"
-CLASS="CALSTABLE"
-><COL><COL><THEAD
-><TR
-><TH
->TERMTYPE</TH
-><TH
->Meaning</TH
-></TR
-></THEAD
-><TBODY
-><TR
-><TD
->00</TD
-><TD
->end of expression</TD
-></TR
-><TR
-><TD
->01</TD
-><TD
->integer (16 bit in big endian order follows)</TD
-></TR
-><TR
-><TD
->02</TD
-><TD
->	external symbol reference (NUL terminated symbol name follows)</TD
-></TR
-><TR
-><TD
->03</TD
-><TD
->local symbol reference (NUL terminated symbol name follows)</TD
-></TR
-><TR
-><TD
->04</TD
-><TD
->operator (1 byte operator number)</TD
-></TR
-><TR
-><TD
->05</TD
-><TD
->section base address reference</TD
-></TR
-><TR
-><TD
->FF</TD
-><TD
->This term will set flags for the expression. Each one of these terms will set a single flag. All of them should be specified first in an expression. If they are not, the behaviour is undefined. The byte following is the flag. Flag 01 indicates an 8 bit relocation. Flag 02 indicates a zero-width relocation (see the EXTDEP pseudo op in LWASM).</TD
-></TR
-></TBODY
-></TABLE
-></DIV
-><P
->External references are resolved using other object files while local
-references are resolved using the local symbol table(s) from this file. This
-allows local symbols that are not exported to have the same names as
-exported symbols or external references.</P
-><DIV
-CLASS="TABLE"
-><A
-NAME="AEN996"
-></A
-><P
-><B
->Table 6-2. Object File Operator Numbers</B
-></P
-><TABLE
-BORDER="1"
-FRAME="border"
-CLASS="CALSTABLE"
-><COL><COL><THEAD
-><TR
-><TH
->Number</TH
-><TH
->Operator</TH
-></TR
-></THEAD
-><TBODY
-><TR
-><TD
->01</TD
-><TD
->addition (+)</TD
-></TR
-><TR
-><TD
->02</TD
-><TD
->subtraction (-)</TD
-></TR
-><TR
-><TD
->03</TD
-><TD
->multiplication (*)</TD
-></TR
-><TR
-><TD
->04</TD
-><TD
->division (/)</TD
-></TR
-><TR
-><TD
->05</TD
-><TD
->modulus (%)</TD
-></TR
-><TR
-><TD
->06</TD
-><TD
->integer division (\) (same as division)</TD
-></TR
-><TR
-><TD
->07</TD
-><TD
->bitwise and</TD
-></TR
-><TR
-><TD
->08</TD
-><TD
->bitwise or</TD
-></TR
-><TR
-><TD
->09</TD
-><TD
->bitwise xor</TD
-></TR
-><TR
-><TD
->0A</TD
-><TD
->boolean and</TD
-></TR
-><TR
-><TD
->0B</TD
-><TD
->boolean or</TD
-></TR
-><TR
-><TD
->0C</TD
-><TD
->unary negation, 2's complement (-)</TD
-></TR
-><TR
-><TD
->0D</TD
-><TD
->unary 1's complement (^)</TD
-></TR
-></TBODY
-></TABLE
-></DIV
-><P
->An expression is represented in a postfix manner with both operands for
-binary operators preceding the operator and the single operand for unary
-operators preceding the operator.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="c879.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->&nbsp;</TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Libraries and LWAR</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
->&nbsp;</TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->&nbsp;</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/index.html	Mon Aug 05 21:07:14 2019 -0600
+++ b/docs/manual/index.html	Mon Aug 05 21:27:09 2019 -0600
@@ -8,7 +8,7 @@
 CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
 REL="NEXT"
 TITLE="Introduction"
-HREF="c10.html"></HEAD
+HREF="c13.html"></HEAD
 ><BODY
 CLASS="BOOK"
 BGCOLOR="#FFFFFF"
@@ -35,9 +35,15 @@
 NAME="AEN4"
 ></A
 >William Astle</H3
+><H3
+CLASS="AUTHOR"
+><A
+NAME="AEN7"
+></A
+>LWTools Contributors </H3
 ><P
 CLASS="COPYRIGHT"
->Copyright &copy; 2009-2013 William Astle</P
+>Copyright &copy; 2009-2015 William Astle and LWTools contributors</P
 ><HR></DIV
 ><DIV
 CLASS="TOC"
@@ -48,167 +54,192 @@
 ></DT
 ><DT
 >1. <A
-HREF="c10.html"
+HREF="c13.html"
 >Introduction</A
 ></DT
 ><DD
 ><DL
 ><DT
 >1.1. <A
-HREF="c10.html#AEN13"
+HREF="c13.html#AEN16"
 >History</A
 ></DT
 ></DL
 ></DD
 ><DT
 >2. <A
-HREF="c18.html"
+HREF="c21.html"
 >Output Formats</A
 ></DT
 ><DD
 ><DL
 ><DT
 >2.1. <A
-HREF="c18.html#AEN21"
+HREF="c21.html#AEN24"
 >Raw Binaries</A
 ></DT
 ><DT
 >2.2. <A
-HREF="x24.html"
+HREF="x27.html"
 >DECB Binaries</A
 ></DT
 ><DT
 >2.3. <A
-HREF="x29.html"
+HREF="x32.html"
+>ASCII Hexadecimal</A
+></DT
+><DT
+>2.4. <A
+HREF="x36.html"
+>Motorola S-Record</A
+></DT
+><DT
+>2.5. <A
+HREF="x41.html"
+>Intel Hex</A
+></DT
+><DT
+>2.6. <A
+HREF="x46.html"
 >OS9 Modules</A
 ></DT
 ><DT
->2.4. <A
-HREF="x37.html"
+>2.7. <A
+HREF="x54.html"
 >Object Files</A
 ></DT
 ></DL
 ></DD
 ><DT
 >3. <A
-HREF="c45.html"
+HREF="c62.html"
 >LWASM</A
 ></DT
 ><DD
 ><DL
 ><DT
 >3.1. <A
-HREF="c45.html#AEN48"
+HREF="c62.html#AEN65"
 >Command Line Options</A
 ></DT
 ><DT
 >3.2. <A
-HREF="x170.html"
+HREF="x229.html"
 >Dialects</A
 ></DT
 ><DT
 >3.3. <A
-HREF="x177.html"
+HREF="x238.html"
 >Source Format</A
 ></DT
 ><DT
 >3.4. <A
-HREF="x187.html"
+HREF="x248.html"
 >Symbols</A
 ></DT
 ><DT
 >3.5. <A
-HREF="x192.html"
+HREF="x253.html"
 >Numbers and Expressions</A
 ></DT
 ><DT
 >3.6. <A
-HREF="x200.html"
+HREF="x261.html"
 >Assembler Directives</A
 ></DT
 ><DD
 ><DL
 ><DT
 >3.6.1. <A
-HREF="x200.html#AEN203"
+HREF="x261.html#AEN264"
 >Data Directives</A
 ></DT
 ><DT
 >3.6.2. <A
-HREF="x200.html#AEN314"
+HREF="x261.html#AEN375"
 >Address Definition</A
 ></DT
 ><DT
 >3.6.3. <A
-HREF="x200.html#AEN361"
+HREF="x261.html#AEN426"
 >Conditional Assembly</A
 ></DT
 ><DT
 >3.6.4. <A
-HREF="x200.html#AEN426"
+HREF="x261.html#AEN497"
 >OS9 Target Directives</A
 ></DT
 ><DT
 >3.6.5. <A
-HREF="x200.html#AEN451"
+HREF="x261.html#AEN522"
 >Miscelaneous Directives</A
 ></DT
 ></DL
 ></DD
 ><DT
 >3.7. <A
-HREF="x491.html"
+HREF="x562.html"
 >Macros</A
 ></DT
 ><DT
 >3.8. <A
-HREF="x514.html"
+HREF="x585.html"
 >Structures</A
 ></DT
 ><DT
 >3.9. <A
-HREF="x535.html"
+HREF="x606.html"
 >Object Files and Sections</A
 ></DT
 ><DT
 >3.10. <A
-HREF="x599.html"
+HREF="x670.html"
 >Assembler Modes and Pragmas</A
 ></DT
+><DT
+>3.11. <A
+HREF="x816.html"
+>Convenience Instructions</A
+></DT
+><DT
+>3.12. <A
+HREF="x821.html"
+>Cycle Counts</A
+></DT
 ></DL
 ></DD
 ><DT
 >4. <A
-HREF="c693.html"
+HREF="c827.html"
 >LWLINK</A
 ></DT
 ><DD
 ><DL
 ><DT
 >4.1. <A
-HREF="c693.html#AEN696"
+HREF="c827.html#AEN830"
 >Command Line Options</A
 ></DT
 ><DT
 >4.2. <A
-HREF="x793.html"
+HREF="x927.html"
 >Linker Operation</A
 ></DT
 ><DT
 >4.3. <A
-HREF="x807.html"
+HREF="x941.html"
 >Linking Scripts</A
 ></DT
 ><DT
 >4.4. <A
-HREF="x864.html"
+HREF="x1007.html"
 >Format Specific Linking Notes</A
 ></DT
 ><DD
 ><DL
 ><DT
 >4.4.1. <A
-HREF="x864.html#AEN867"
+HREF="x1007.html#AEN1010"
 >OS9 Modules</A
 ></DT
 ></DL
@@ -217,21 +248,21 @@
 ></DD
 ><DT
 >5. <A
-HREF="c879.html"
+HREF="c1022.html"
 >Libraries and LWAR</A
 ></DT
 ><DD
 ><DL
 ><DT
 >5.1. <A
-HREF="c879.html#AEN883"
+HREF="c1022.html#AEN1026"
 >Command Line Options</A
 ></DT
 ></DL
 ></DD
 ><DT
 >6. <A
-HREF="c941.html"
+HREF="c1084.html"
 >Object Files</A
 ></DT
 ></DL
@@ -246,12 +277,12 @@
 ></DT
 ><DT
 >6-1. <A
-HREF="c941.html#AEN966"
+HREF="c1084.html#AEN1109"
 >Object File Term Types</A
 ></DT
 ><DT
 >6-2. <A
-HREF="c941.html#AEN996"
+HREF="c1084.html#AEN1139"
 >Object File Operator Numbers</A
 ></DT
 ></DL
@@ -283,7 +314,7 @@
 ALIGN="right"
 VALIGN="top"
 ><A
-HREF="c10.html"
+HREF="c13.html"
 ACCESSKEY="N"
 >Next</A
 ></TD
--- a/docs/manual/manual.html	Mon Aug 05 21:07:14 2019 -0600
+++ b/docs/manual/manual.html	Mon Aug 05 21:27:09 2019 -0600
@@ -32,9 +32,15 @@
 NAME="AEN4"
 ></A
 >William Astle</H3
+><H3
+CLASS="AUTHOR"
+><A
+NAME="AEN7"
+></A
+>LWTools Contributors </H3
 ><P
 CLASS="COPYRIGHT"
->Copyright &copy; 2009-2013 William Astle</P
+>Copyright &copy; 2009-2015 William Astle and LWTools contributors</P
 ><HR></DIV
 ><DIV
 CLASS="TOC"
@@ -45,167 +51,192 @@
 ></DT
 ><DT
 >1. <A
-HREF="#AEN10"
+HREF="#AEN13"
 >Introduction</A
 ></DT
 ><DD
 ><DL
 ><DT
 >1.1. <A
-HREF="#AEN13"
+HREF="#AEN16"
 >History</A
 ></DT
 ></DL
 ></DD
 ><DT
 >2. <A
-HREF="#AEN18"
+HREF="#AEN21"
 >Output Formats</A
 ></DT
 ><DD
 ><DL
 ><DT
 >2.1. <A
-HREF="#AEN21"
+HREF="#AEN24"
 >Raw Binaries</A
 ></DT
 ><DT
 >2.2. <A
-HREF="#AEN24"
+HREF="#AEN27"
 >DECB Binaries</A
 ></DT
 ><DT
 >2.3. <A
-HREF="#AEN29"
+HREF="#AEN32"
+>ASCII Hexadecimal</A
+></DT
+><DT
+>2.4. <A
+HREF="#AEN36"
+>Motorola S-Record</A
+></DT
+><DT
+>2.5. <A
+HREF="#AEN41"
+>Intel Hex</A
+></DT
+><DT
+>2.6. <A
+HREF="#AEN46"
 >OS9 Modules</A
 ></DT
 ><DT
->2.4. <A
-HREF="#AEN37"
+>2.7. <A
+HREF="#AEN54"
 >Object Files</A
 ></DT
 ></DL
 ></DD
 ><DT
 >3. <A
-HREF="#AEN45"
+HREF="#AEN62"
 >LWASM</A
 ></DT
 ><DD
 ><DL
 ><DT
 >3.1. <A
-HREF="#AEN48"
+HREF="#AEN65"
 >Command Line Options</A
 ></DT
 ><DT
 >3.2. <A
-HREF="#AEN170"
+HREF="#AEN229"
 >Dialects</A
 ></DT
 ><DT
 >3.3. <A
-HREF="#AEN177"
+HREF="#AEN238"
 >Source Format</A
 ></DT
 ><DT
 >3.4. <A
-HREF="#AEN187"
+HREF="#AEN248"
 >Symbols</A
 ></DT
 ><DT
 >3.5. <A
-HREF="#AEN192"
+HREF="#AEN253"
 >Numbers and Expressions</A
 ></DT
 ><DT
 >3.6. <A
-HREF="#AEN200"
+HREF="#AEN261"
 >Assembler Directives</A
 ></DT
 ><DD
 ><DL
 ><DT
 >3.6.1. <A
-HREF="#AEN203"
+HREF="#AEN264"
 >Data Directives</A
 ></DT
 ><DT
 >3.6.2. <A
-HREF="#AEN314"
+HREF="#AEN375"
 >Address Definition</A
 ></DT
 ><DT
 >3.6.3. <A
-HREF="#AEN361"
+HREF="#AEN426"
 >Conditional Assembly</A
 ></DT
 ><DT
 >3.6.4. <A
-HREF="#AEN426"
+HREF="#AEN497"
 >OS9 Target Directives</A
 ></DT
 ><DT
 >3.6.5. <A
-HREF="#AEN451"
+HREF="#AEN522"
 >Miscelaneous Directives</A
 ></DT
 ></DL
 ></DD
 ><DT
 >3.7. <A
-HREF="#AEN491"
+HREF="#AEN562"
 >Macros</A
 ></DT
 ><DT
 >3.8. <A
-HREF="#AEN514"
+HREF="#AEN585"
 >Structures</A
 ></DT
 ><DT
 >3.9. <A
-HREF="#AEN535"
+HREF="#AEN606"
 >Object Files and Sections</A
 ></DT
 ><DT
 >3.10. <A
-HREF="#AEN599"
+HREF="#AEN670"
 >Assembler Modes and Pragmas</A
 ></DT
+><DT
+>3.11. <A
+HREF="#CONVINST"
+>Convenience Instructions</A
+></DT
+><DT
+>3.12. <A
+HREF="#AEN821"
+>Cycle Counts</A
+></DT
 ></DL
 ></DD
 ><DT
 >4. <A
-HREF="#AEN693"
+HREF="#AEN827"
 >LWLINK</A
 ></DT
 ><DD
 ><DL
 ><DT
 >4.1. <A
-HREF="#AEN696"
+HREF="#AEN830"
 >Command Line Options</A
 ></DT
 ><DT
 >4.2. <A
-HREF="#AEN793"
+HREF="#AEN927"
 >Linker Operation</A
 ></DT
 ><DT
 >4.3. <A
-HREF="#AEN807"
+HREF="#AEN941"
 >Linking Scripts</A
 ></DT
 ><DT
 >4.4. <A
-HREF="#AEN864"
+HREF="#AEN1007"
 >Format Specific Linking Notes</A
 ></DT
 ><DD
 ><DL
 ><DT
 >4.4.1. <A
-HREF="#AEN867"
+HREF="#AEN1010"
 >OS9 Modules</A
 ></DT
 ></DL
@@ -214,14 +245,14 @@
 ></DD
 ><DT
 >5. <A
-HREF="#AEN879"
+HREF="#AEN1022"
 >Libraries and LWAR</A
 ></DT
 ><DD
 ><DL
 ><DT
 >5.1. <A
-HREF="#AEN883"
+HREF="#AEN1026"
 >Command Line Options</A
 ></DT
 ></DL
@@ -243,12 +274,12 @@
 ></DT
 ><DT
 >6-1. <A
-HREF="#AEN966"
+HREF="#AEN1109"
 >Object File Term Types</A
 ></DT
 ><DT
 >6-2. <A
-HREF="#AEN996"
+HREF="#AEN1139"
 >Object File Operator Numbers</A
 ></DT
 ></DL
@@ -257,7 +288,7 @@
 CLASS="CHAPTER"
 ><HR><H1
 ><A
-NAME="AEN10"
+NAME="AEN13"
 ></A
 >Chapter 1. Introduction</H1
 ><P
@@ -269,7 +300,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN13"
+NAME="AEN16"
 >1.1. History</A
 ></H2
 ><P
@@ -300,7 +331,7 @@
 CLASS="CHAPTER"
 ><HR><H1
 ><A
-NAME="AEN18"
+NAME="AEN21"
 ></A
 >Chapter 2. Output Formats</H1
 ><P
@@ -311,7 +342,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN21"
+NAME="AEN24"
 >2.1. Raw Binaries</A
 ></H2
 ><P
@@ -325,7 +356,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN24"
+NAME="AEN27"
 >2.2. DECB Binaries</A
 ></H2
 ><P
@@ -350,8 +381,84 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN29"
->2.3. OS9 Modules</A
+NAME="AEN32"
+>2.3. ASCII Hexadecimal</A
+></H2
+><P
+>This human-readable ASCII hexadecimal format consists of CR+LF terminated 
+lines of ASCII text. Each line has the following structure: a zero-padded 
+four-digit ASCII hex address, a colon separator, and one or more zero-padded
+two-digit hex values separated by commas. ASCII Hexadecimal format favors 
+paragraph-aligned addresses (i.e. a least significant address nybble value
+of zero). During output, the number of hex values on each line are adjusted
+to align the address of the next line on a paragraph boundary. The sequence 
+of addresses in the ASCII Hexadecimal file directly follows that of the source
+file; multiple ORG directives in the source code may result in out-of-sequence
+addresses in the ASCII Hexadecimal output.</P
+><P
+>LWASM can output this format since version 4.10.</P
+></DIV
+><DIV
+CLASS="SECTION"
+><HR><H2
+CLASS="SECTION"
+><A
+NAME="AEN36"
+>2.4. Motorola S-Record</A
+></H2
+><P
+>This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+"S", an ASCII record type digit (0-9), a two-digit ASCII hex byte count, a 
+four-digit ASCII hex address, an optional sequence of two-digit ASCII hex data
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only S0, 
+S1, S5 and S9 record types. S1 records are limited to maximum of 16 data bytes
+in length, and  paragraph alignment of addresses is favored. The address
+sequence of the S-Records directly follows that of the source file; multiple
+ORG directives in the source code may result in out-of-sequence addresses in
+the S-Record output. </P
+><P
+>Motorola S-Record format is a standard ASCII format accepted by most memory
+device programming equipment. It is particularly useful when the assembled 
+code output is destined to reside within an EPROM or Flash memory device,
+for example.</P
+><P
+>LWASM can output this format since version 4.10. LWLINK can output this format
+since version 4.11.</P
+></DIV
+><DIV
+CLASS="SECTION"
+><HR><H2
+CLASS="SECTION"
+><A
+NAME="AEN41"
+>2.5. Intel Hex</A
+></H2
+><P
+>This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+":", a two-digit ASCII hex byte count, a four-digit ASCII hex address, a two-
+digit ASCII hex record type, an optional sequence of two-digit ASCII hex data 
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only 00, 
+and 01 Intel Hex record types. Data records are limited to maximum of 16 
+data bytes in length, and paragraph alignment of addresses is favored. The 
+address sequence of the Intel hex records directly follows that of the source 
+file; multiple ORG directives in the source code may result in out-of-sequence 
+addresses in the Intel Hex output. </P
+><P
+>Intel Hex format is the other standard ASCII format accepted by most memory 
+device programming equipment, it and the Motorola S-Record format are used for
+similar purposes.</P
+><P
+>LWASM can output this format since version 4.10.</P
+></DIV
+><DIV
+CLASS="SECTION"
+><HR><H2
+CLASS="SECTION"
+><A
+NAME="AEN46"
+>2.6. OS9 Modules</A
 ></H2
 ><P
 >&#13;Since version 2.5, LWASM is able to generate OS9 modules. The syntax is
@@ -386,8 +493,8 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN37"
->2.4. Object Files</A
+NAME="AEN54"
+>2.7. Object Files</A
 ></H2
 ><P
 >LWASM supports generating a proprietary object file format which is
@@ -423,7 +530,7 @@
 CLASS="CHAPTER"
 ><HR><H1
 ><A
-NAME="AEN45"
+NAME="AEN62"
 ></A
 >Chapter 3. LWASM</H1
 ><P
@@ -435,7 +542,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN48"
+NAME="AEN65"
 >3.1. Command Line Options</A
 ></H2
 ><P
@@ -459,6 +566,22 @@
 >This will cause the assembler to accept the additional instructions available
 on the 6309 processor. This is the default mode; this option is provided for
 completeness and to override preset command arguments.</P
+><P
+>This option is the same as if the first line of the source code is "PRAGMA 6309".</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--6800compat</CODE
+></DT
+><DD
+><P
+>This is equivalent to <CODE
+CLASS="OPTION"
+>--pragma=6800compat</CODE
+>.</P
+><P
+>This will enable recognition of 6800 compatibility instructions.</P
 ></DD
 ><DT
 ><CODE
@@ -471,7 +594,8 @@
 ><DD
 ><P
 >This will cause the assembler to reject instructions that are only available
-on the 6309 processor.</P
+on the 6309 processor. This actually has the effect of starting the assembler
+as though the first line of the source is "PRAGMA 6809".</P
 ></DD
 ><DT
 ><CODE
@@ -514,11 +638,22 @@
 <CODE
 CLASS="OPTION"
 >os9</CODE
-> for creating OS9 modules, and <CODE
+> for creating OS9 modules, <CODE
 CLASS="OPTION"
 >raw</CODE
 > for
-a raw binary.</P
+a raw binary, <CODE
+CLASS="OPTION"
+>hex</CODE
+> for ASCII hexadecminal format, 
+<CODE
+CLASS="OPTION"
+>srec</CODE
+> for Motorola S-Record format, and <CODE
+CLASS="OPTION"
+>ihex</CODE
+>
+ for Intel Hex format.</P
 ></DD
 ><DT
 ><CODE
@@ -544,6 +679,24 @@
 ><DT
 ><CODE
 CLASS="OPTION"
+>--symbol-dump[=file]</CODE
+></DT
+><DD
+><P
+>Cause LWASM to output the global symbol table in assembly source format. If
+<CODE
+CLASS="OPTION"
+>file</CODE
+> is specified, the table output will go to the specified
+file. Otherwise, it will go to the standard output stream. Local symbols will
+not be included. Incomplete symbols will be defined to zero with a comment
+indicating incompleteness. Symbols defined with SET will also be listed using
+SET in the symbol dump. However, if the symbol is defined multiple times, the
+order of the definitions in the dump file is undefined.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
 >--symbols</CODE
 >, <CODE
 CLASS="OPTION"
@@ -557,6 +710,27 @@
 ><DT
 ><CODE
 CLASS="OPTION"
+>--symbols-nolocals</CODE
+></DT
+><DD
+><P
+>Behaves just like <CODE
+CLASS="OPTION"
+>--symbols</CODE
+> but with local labels omitted.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
+>--map=FILE</CODE
+></DT
+><DD
+><P
+>&#13;This option generates a map file which can be used by debuggers and monitors to provide symbol information. A map file may be created independent of a listing file. (Patches are pending for MAME and exec09.)&#13;</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
 >--obj</CODE
 ></DT
 ><DD
@@ -582,6 +756,15 @@
 ><DT
 ><CODE
 CLASS="OPTION"
+>--no-output</CODE
+></DT
+><DD
+><P
+>Do assembly as usual but suppress generation of the output file.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
 >--pragma=pragma</CODE
 >, <CODE
 CLASS="OPTION"
@@ -639,6 +822,25 @@
 ><DT
 ><CODE
 CLASS="OPTION"
+>-t WIDTH</CODE
+>, <CODE
+CLASS="OPTION"
+>--tabs=WIDTH</CODE
+></DT
+><DD
+><P
+>Specifies the handling of tabs in listing files. <CODE
+CLASS="OPTION"
+>--tabs=0</CODE
+>
+disables tab expansion. <CODE
+CLASS="OPTION"
+>--tabs=8</CODE
+> is the default setting.</P
+></DD
+><DT
+><CODE
+CLASS="OPTION"
 >--help</CODE
 >, <CODE
 CLASS="OPTION"
@@ -690,18 +892,28 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN170"
+NAME="AEN229"
 >3.2. Dialects</A
 ></H2
 ><P
->LWASM supports all documented MC6809 instructions as defined by Motorola. 
-It also supports all known HD6309 instructions.  While there is general
-agreement on the pneumonics for most of the 6309 instructions, there is some
-variance with the block transfer instructions. TFM for all four variations
-seems to have gained the most traction and, thus, this is the form that is
-recommended for LWASM. However, it also supports COPY, COPY-, IMP, EXP,
-TFRP, TFRM, TFRS, and TFRR. It further adds COPY+ as a synomym for COPY,
-IMPLODE for IMP, and EXPAND for EXP.</P
+> LWASM supports all documented MC6809 instructions as defined by
+Motorola.  By default, this does not include any MC6800 compatibility
+instructions.  As of LWASM 4.11, those compatibility instructions can be
+enabled using the <CODE
+CLASS="PARAMETER"
+>--6800compat</CODE
+> option or the
+<CODE
+CLASS="PARAMETER"
+>6800compat</CODE
+> pragma.  It also supports all known HD6309
+instructions.  While there is general agreement on the pneumonics for most
+of the 6309 instructions, there is some variance with the block transfer
+instructions.  TFM for all four variations seems to have gained the most
+traction and, thus, this is the form that is recommended for LWASM. 
+However, it also supports COPY, COPY-, IMP, EXP, TFRP, TFRM, TFRS, and TFRR. 
+It further adds COPY+ as a synomym for COPY, IMPLODE for IMP, and EXPAND for
+EXP.  </P
 ><P
 >By default, LWASM accepts 6309 instructions. However, using the
 <CODE
@@ -724,7 +936,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN177"
+NAME="AEN238"
 >3.3. Source Format</A
 ></H2
 ><P
@@ -770,7 +982,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN187"
+NAME="AEN248"
 >3.4. Symbols</A
 ></H2
 ><P
@@ -798,7 +1010,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN192"
+NAME="AEN253"
 >3.5. Numbers and Expressions</A
 ></H2
 ><P
@@ -843,7 +1055,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN200"
+NAME="AEN261"
 >3.6. Assembler Directives</A
 ></H2
 ><P
@@ -856,7 +1068,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN203"
+NAME="AEN264"
 >3.6.1. Data Directives</A
 ></H3
 ><P
@@ -1067,10 +1279,10 @@
 ><DT
 >FILL <CODE
 CLASS="PARAMETER"
->size</CODE
+>byte</CODE
 >,<CODE
 CLASS="PARAMETER"
->byte</CODE
+>size</CODE
 ></DT
 ><DD
 ><P
@@ -1090,7 +1302,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN314"
+NAME="AEN375"
 >3.6.2. Address Definition</A
 ></H3
 ><P
@@ -1110,10 +1322,20 @@
 ><P
 >Set the assembly address. The address must be fully resolvable on the
 first pass so no external or forward references are permitted. ORG is not
-permitted within sections when outputting to object files. For the DECB
-target, each ORG directive after which output is generated will cause
-a new preamble to be output. ORG is only used to determine the addresses
-of symbols when the raw target is used.</P
+permitted within sections when outputting to object files. For target formats
+that include address information (decb, hex, srec, and ihex), an ORG 
+directive will re-start the address sequence within the output. When using
+the raw target format, ORG is used only to determine the addresses of symbols.</P
+></DD
+><DT
+>REORG</DT
+><DD
+><P
+>Sets the assembly address to the value it had immediately prior to the
+previous ORG statement. It is used to continue assembly after some
+specification that required an additional ORG. This directive is primarily
+intended for MACRO-80c compatibility. Consider using alternatives in
+modern code.</P
 ></DD
 ><DT
 ><CODE
@@ -1226,7 +1448,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN361"
+NAME="AEN426"
 >3.6.3. Conditional Assembly</A
 ></H3
 ><P
@@ -1350,6 +1572,18 @@
 will be considered true.</P
 ></DD
 ><DT
+>IFPRAGMA <CODE
+CLASS="PARAMETER"
+>pragma</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>pragma</CODE
+> is in effect, the condition will be considered true.</P
+></DD
+><DT
 >IFNDEF <CODE
 CLASS="PARAMETER"
 >sym</CODE
@@ -1389,7 +1623,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN426"
+NAME="AEN497"
 >3.6.4. OS9 Target Directives</A
 ></H3
 ><P
@@ -1456,7 +1690,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN451"
+NAME="AEN522"
 >3.6.5. Miscelaneous Directives</A
 ></H3
 ><P
@@ -1570,7 +1804,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN491"
+NAME="AEN562"
 >3.7. Macros</A
 ></H2
 ><P
@@ -1669,7 +1903,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN514"
+NAME="AEN585"
 >3.8. Structures</A
 ></H2
 ><P
@@ -1762,7 +1996,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN535"
+NAME="AEN606"
 >3.9. Object Files and Sections</A
 ></H2
 ><P
@@ -1979,7 +2213,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN599"
+NAME="AEN670"
 >3.10. Assembler Modes and Pragmas</A
 ></H2
 ><P
@@ -2066,6 +2300,49 @@
 CLASS="VARIABLELIST"
 ><DL
 ><DT
+>6800compat</DT
+><DD
+><P
+>When in force, this pragma enables recognition of various
+compatibility instructions useful when assembling 6800 code.  These
+compatibility instructions are assembled into equivalent 6809 instructions. 
+This mode also includes several analogous instructions which are not
+strictly 6800 instructions but allow the similar style to be applied to 6809
+specific features.</P
+><P
+>Technically, a compliant 6809 assembler must recognize these
+instructions by default since Motorola advertised the 6809 as being source
+compatible with the 6800.  However, most source code does not require this
+compatibility and LWASM itself did not support these instructions prior to
+version 4.11 so this mode is disabled by default.</P
+></DD
+><DT
+>6809</DT
+><DD
+><P
+>This pragma allows you to mark a section of code as 6809-only. In ths mode,
+the assembler will throw an error if any 6309 instructions are used.</P
+></DD
+><DT
+>6309</DT
+><DD
+><P
+>This pragma enables the use of 6309 instructions and disables any 6809 specific
+instructions. It also changes the cycle count listing output (if selected)
+to display 6309 timings.</P
+></DD
+><DT
+>6809conv, 6309conv</DT
+><DD
+><P
+>These pragmas enable convenience instructions extending the 6809 and 6309
+instruction sets respectively. For more information, see 
+<A
+HREF="#CONVINST"
+>Section 3.11</A
+>.</P
+></DD
+><DT
 >index0tonone</DT
 ><DD
 ><P
@@ -2230,6 +2507,128 @@
 yet evaluate to a constant value at the point where the conditional appears,
 the assembler will still complain about a non constant condition.</P
 ></DD
+><DT
+>forwardrefmax</DT
+><DD
+><P
+>This pragma will disable forward reference optimization completely.
+Ordinarily, LWASM will attempt to select the shortest possible addressing
+mode for forward references.  However, in many source files, especially
+those not using the PCR relative addressing modes, this optimization is
+pointless since the assembler will almost certainly settle on a 16 bit
+offset or address.  If all variables in the direct page are defined before
+the main body of the code, the benefit of forward reference optimization
+almost certainly vanishes completely.  However, the cost of doing that
+optimization remains and can result in a very long assembly time.</P
+><P
+>Enabling this pragma will cause all forward references to use the
+maximum offset or address size, much the same has EDTASM and other pure
+two pass assemblers do. The side effect is that all line lengths and
+symbol values are fully resolved after the initial parsing pass and the
+amount of work to resolve everything becomes almost nil.</P
+><P
+>While this pragma can be applied selectively to sections of source
+code (use *PRAGMA if doing so and compatibility with other assemblers
+is desired), it is likely more useful when provided as a command line
+pragma.</P
+><P
+>It should be noted that the presence or absence of this pragma
+will not change the correctness of the generated code unless cycle counts
+or byte counts are critical (which they usually are not). It also will
+not override the operand size override prefixes (&lt; and &gt;). It only
+applies when the assembler is left to guess what the operand size is.</P
+></DD
+><DT
+>operandsizewarning</DT
+><DD
+><P
+>Enabling this pragma will cause LWASM to show a warning when it
+detects that a smaller addressing mode could be used for an instruction.
+This is particularly useful for finding places where long branches are used
+where short branches could be used instead. It will also show the warnings
+for indexing offsets (regardless of whether the operand size is
+forced).</P
+><P
+>As of LWASM 4.16, no other checks are performed.</P
+></DD
+><DT
+>qrts</DT
+><DD
+><P
+>&#13;Enables the use of the ?RTS branch target. ?RTS is implemented to maintain
+compatibility with the MACRO-80c assembler.  It works by searching backward
+in the code for an RTS instruction.  If none is found, it inverts the branch
+logic and inserts an RTS following the branch instruction.  Below you can
+see how a BMI (2B xx) has been assembled as a BPL *+1 (2A 01) to skip over an
+inserted RTS (39).</P
+><PRE
+CLASS="PROGRAMLISTING"
+>1D1E 7D1D1D            TST   WHICH1
+1D21 2A0139            BMI   ?RTS
+1D24 BD1D65            JSR   INV</PRE
+></DD
+><DT
+>m80ext</DT
+><DD
+><P
+>&#13;This pragma (along with pragma qrts) enables some uncommon behaviors to
+accomodate The Micro Works MACRO-80c assembler from 1982.  This assembler
+was used by a number of notable TRS-80 Color Computer applications and the
+goal of this pragma is to allow them to build identical binaries from
+unmodified, vintage source code.</P
+><P
+>&#13;In m80ext mode, the handling of the "END" pseudo-op changes when used inside
+an include file.  Instead of terminating all assembly, it merely stops
+processing of the current include file (this behavior matches the original
+Motorola 6809 assembler).  In addition, loading an ASCII value with a single
+quote (e.g., LDA #'N) is extended to 16-bit registers (e.g., LDD #'NO). 
+LWASM normally supports this via double quote and that is the proper use in
+modern code.  Finally, the FCC pseudo-op is extended to handle FCB-like
+behavior after the closing delimiter:</P
+><PRE
+CLASS="PROGRAMLISTING"
+>                       FCC "Greetings from 1982",13,0</PRE
+></DD
+><DT
+>testmode</DT
+><DD
+><P
+>&#13;This pragma is intended for internal testing purposes. In testmode, the
+assembler searches for a specially-formatted comment starting with a
+semicolon followed by a period.  Immediately afterward are a list of hex
+bytes that the assembler is expected to generate.  Likewise, if the
+assembler is expected to throw an error or warning on a given line, you can
+check by specifying "E:" followed by the error number.  In this case the
+error is ignored and the assembler continues ignoring the line in question.&#13;</P
+><PRE
+CLASS="PROGRAMLISTING"
+>1D1E 7D1D1D            TST   WHICH1    ;.7d1d1d
+1D21 2A0139            BMI   ?RTS      ;.2a0139
+1D24 1D24              FDB   *         ;.1d24
+1D26                   xyz   INV       ;.E:32    (Error 32 is "Bad opcode")</PRE
+></DD
+><DT
+>emuext</DT
+><DD
+><P
+>&#13;This pragma enables two instructions useful when running code in compatible
+emulators. Break breaks into the debugger. Log writes printf-style
+output to the debug window&#13;</P
+><PRE
+CLASS="PROGRAMLISTING"
+>      LOG           ; log output
+      FDB   FSTR    ; pointer to format string
+      FDB   PX1     ; 16 bit pointer to 16 bit value
+      FDB   PY1     ; 16 bit pointer to 8 bit value (see format string!)
+      FDB   PX2     ; 16 bit pointer to 16 bit value
+      FDB   PY2     ; 16 bit pointer to 8 bit value
+      ; execution continues here ...
+      RTS
+
+; format string
+FSTR  FCC   "%hu,%hhu - %hu,%hhu"
+      FCB   10,0</PRE
+></DD
 ></DL
 ></DIV
 ><P
@@ -2249,12 +2648,76 @@
 file to operate under the nolist pragma.  However, if the file is included
 while nolist is already engaged, it will not undo that state.</P
 ></DIV
+><DIV
+CLASS="SECTION"
+><HR><H2
+CLASS="SECTION"
+><A
+NAME="CONVINST"
+>3.11. Convenience Instructions</A
+></H2
+><P
+>&#13;Similar to the 6800 compatibility instructions (pragma 6800compat) these
+pragma 6809conv and pragma 6309conv enable convenience extensions to the
+6809 and 6309 instruction set.  Originally intended for compatibility with
+the MACRO-80c assembler, these have proven useful in large codebases that
+target both the 6809 and the 6309.</P
+><P
+>&#13;The 6809 extensions are straightforward with the exception of "TSTD" which
+assembles as "STD -2,S".  A benefit of using these is they will "just work"
+and take on their 6309 equivalent when you enable 6309 assembly mode. 
+Supported instructions: ASRD, CLRD,   COMD,   LSLD,   LSRD,   NEGD,   TSTD.</P
+><P
+>&#13;6309 extensions are based on common patterns described by Chris Burke and
+Darren Atkinson in their 6309 documentation and include the following
+instructions: ASRQ,   CLRQ,   COMQ,   LSLE,   LSLF,   LSLQ,   LSRQ,   NEGE,
+   NEGF,   NEGW,   NEGQ,   TSTQ.</P
+></DIV
+><DIV
+CLASS="SECTION"
+><HR><H2
+CLASS="SECTION"
+><A
+NAME="AEN821"
+>3.12. Cycle Counts</A
+></H2
+><P
+>&#13;The following options for displaying cycle counts in listings are provided.
+These options are enabled from pragmas on the command line or in the
+assembly files themselves.  For compatibility with other assemblers you can
+use the "OPT" keyword in addition to "PRAGMA."</P
+><PRE
+CLASS="PROGRAMLISTING"
+>opt c  - enable cycle counts: [8]
+opt cd - enable detailed cycle counts breaking down addressing modes: [5+3]
+opt ct - show a running subtotal of cycles
+opt cc - clear the running subtotal</PRE
+><P
+>&#13;The assembler supports both 6809 as well as native-mode 6309 cycle counts.
+In 6309 mode the counts are displayed in parenthesis instead of brackets. 
+In addition, some operations have a variable cycle count.  In this case a
+"+?" is displayed to alert the reader.  Sample output is shown below.</P
+><PRE
+CLASS="PROGRAMLISTING"
+>266f 7d25e2     (window.asm):00313 [7]     7       move   tst   putflg
+2672 2602       (window.asm):00314 [5]     12             bne   a@
+2674 1e13       (window.asm):00315 [8]     20             exg   x,u
+2676 0dd6       (window.asm):00316 [6]     26      a@     tst   is6309
+2678 2618       (window.asm):00317 [5]     31             bne   exit@
+                (window.asm):00318                        opt   6309
+267a 10860085   (window.asm):00319 (4)     35      b@     ldw   #133
+267e 113813     (window.asm):00320 (6+?)   41             tfm   x+,u+
+2681 30881b     (window.asm):00321 (4+1)   46             leax  27,x
+2684 33c81b     (window.asm):00322 (4+1)   51             leau  27,u
+2687 4a         (window.asm):00323 (1)     52             deca
+2688 26f0       (window.asm):00324 (5)     57             bne   b@</PRE
+></DIV
 ></DIV
 ><DIV
 CLASS="CHAPTER"
 ><HR><H1
 ><A
-NAME="AEN693"
+NAME="AEN827"
 ></A
 >Chapter 4. LWLINK</H1
 ><P
@@ -2265,7 +2728,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN696"
+NAME="AEN830"
 >4.1. Command Line Options</A
 ></H2
 ><P
@@ -2391,8 +2854,9 @@
 ></DT
 ><DD
 ><P
->Load a library using the library search path. LIBSPEC will have "lib" prepended
-and ".a" appended.</P
+>Load a library using the library search path. If LIBSPEC is prefixed with a
+colon (":"), then LIBSPEC is the precise filename to be searched for in the
+library path. Otherwise, LIBSPEC will have "lib" prepended and ".a" appended.</P
 ></DD
 ><DT
 ><CODE
@@ -2462,7 +2926,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN793"
+NAME="AEN927"
 >4.2. Linker Operation</A
 ></H2
 ><P
@@ -2518,7 +2982,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN807"
+NAME="AEN941"
 >4.3. Linking Scripts</A
 ></H2
 ><P
@@ -2650,6 +3114,32 @@
 >section <CODE
 CLASS="PARAMETER"
 >name</CODE
+> high <CODE
+CLASS="PARAMETER"
+>addr</CODE
+></DT
+><DD
+><P
+>&#13;This causes the section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> to load with its end
+address just below <CODE
+CLASS="PARAMETER"
+>addr</CODE
+>.  Subsequent sections are
+loaded at progressively lower addresses.  This may lead to inefficient file
+encoding for some targets.  As of this writing, it will also almost
+certainly do the wrong thing for a raw target.&#13;</P
+><P
+>&#13;This is useful for aligning a block of code with high memory.  As an
+example, if the total size of a section is $100 bytes and a high address of
+$FE00 is specified, the section will actually load at $FD00.&#13;</P
+></DD
+><DT
+>section <CODE
+CLASS="PARAMETER"
+>name</CODE
 ></DT
 ><DD
 ><P
@@ -2696,7 +3186,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN864"
+NAME="AEN1007"
 >4.4. Format Specific Linking Notes</A
 ></H2
 ><P
@@ -2709,7 +3199,7 @@
 ><HR><H3
 CLASS="SECTION"
 ><A
-NAME="AEN867"
+NAME="AEN1010"
 >4.4.1. OS9 Modules</A
 ></H3
 ><P
@@ -2785,7 +3275,7 @@
 CLASS="CHAPTER"
 ><HR><H1
 ><A
-NAME="AEN879"
+NAME="AEN1022"
 ></A
 >Chapter 5. Libraries and LWAR</H1
 ><P
@@ -2804,7 +3294,7 @@
 ><HR><H2
 CLASS="SECTION"
 ><A
-NAME="AEN883"
+NAME="AEN1026"
 >5.1. Command Line Options</A
 ></H2
 ><P
@@ -3005,7 +3495,7 @@
 ><DIV
 CLASS="TABLE"
 ><A
-NAME="AEN966"
+NAME="AEN1109"
 ></A
 ><P
 ><B
@@ -3077,7 +3567,7 @@
 ><DIV
 CLASS="TABLE"
 ><A
-NAME="AEN996"
+NAME="AEN1139"
 ></A
 ><P
 ><B
Binary file docs/manual/manual.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x1007.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,224 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Format Specific Linking Notes</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWLINK"
+HREF="c827.html"><LINK
+REL="PREVIOUS"
+TITLE="Linking Scripts"
+HREF="x941.html"><LINK
+REL="NEXT"
+TITLE="Libraries and LWAR"
+HREF="c1022.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x941.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 4. LWLINK</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c1022.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN1007"
+>4.4. Format Specific Linking Notes</A
+></H1
+><P
+>Some formats require special information to be able to generate actual
+binaries.  If the specific format you are interested in is not listed in
+this section, then there is nothing special you need to know about to create
+a final binary.</P
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN1010"
+>4.4.1. OS9 Modules</A
+></H2
+><P
+>OS9 modules need to embed several items into the module header. These
+items are the type of module, the langauge of the module, the module
+attributes, the module revision number, the data size (bss), and the
+execution offset.  These are all either calculated or default to reasonable
+values.</P
+><P
+>The data size is calcuated as the sum of all sections named "bss" or
+".bss" in all object files that are linked together.</P
+><P
+>The execution offset is calculated from the address of the special
+symbol "__start" which must be an exported (external) symbol in one of the
+objects to be linked.</P
+><P
+>The type defaults to "Prgrm" or "Program module". The language
+defaults to "Objct" or "6809 object code".  Attributes default to enabling
+the re-entrant flag.  And finally, the revision defaults to zero.</P
+><P
+>The embedded module name is the output filename. If the output
+filename includes more than just the filename, this will probably not be
+what you want.</P
+><P
+>The type, language, attributes, revision, and module name can all be
+overridden by providing a special section in exactly one of the object files
+to be linked.  This section is called "__os9" (note the two underscores). 
+To override the type, language, attributes, or revision values, define a
+non-exported symbol in this section called "type", "lang", "attr", or "rev"
+respectively.  Any other symbols defined are ignored.  To override the
+module name, include as the only actual code in the section a NUL terminated
+string (the FCN directive is useful for this).  If there is no code in the
+section or it beings with a NUL, the default name will be used.  Any of the
+preceeding that are not defined in the special section will retain their
+default values.</P
+><P
+>The built-in link script for OS9 modules will place the following
+sections, in order, in the module: "code", ".text", "data", ".data".  It
+will merge all sections with the name "bss" or ".bss" into the "data"
+section.  All other section names are ignored.  What this means is that you
+must define your data variables in the a section called "bss" or ".bss" even
+though you will be refencing them all as offsets from U.  This does have the
+unpleasant side effect that all BSS references will end up being 16 bit
+offsets because the assembler cannot know what the offset will be once the
+linker is finished its work.  Thus, if the tightest possible code is
+required, having LWASM directly output the module is a better choice.</P
+><P
+>While the built-in link script is probably sufficient for most
+purposes, you can provide your own script.  If you provide a custom link
+script, you must start your code and data sections at location 000D to
+accommodate the module header.  Otherwise, you will have an incorrect
+location for the execution offset.  You must use the ENTRY directive in the
+script to define the entry point for the module.</P
+><P
+>It should also be obvious from the above that you cannot mix the bss
+(rmb) definitions with the module code when linking separately.  Those
+familiar with typical module creation will probably find this an unpleasant
+difference but it is unavoidable.</P
+><P
+>It should also be noted that direct page references should also be
+avoided because you cannot know ahead of time whether the linker is going to
+end up putting a particular variable in the first 256 bytes of the module's
+data space.  If, however, you know for certain you will have less than 256
+bytes of defined data space across all of the object files that will be
+linked, you can instead use forced DP addressing for your data addresses
+instead of the ,u notation.  When linking with 3rd party libraries, this
+practice should be avoided.  Also, when creating libraries, always use the
+offset from U technique.</P
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x941.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c1022.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linking Scripts</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c827.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Libraries and LWAR</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x170.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Dialects</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="NEXT"
-TITLE="Source Format"
-HREF="x177.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="c45.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x177.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN170"
->3.2. Dialects</A
-></H1
-><P
->LWASM supports all documented MC6809 instructions as defined by Motorola. 
-It also supports all known HD6309 instructions.  While there is general
-agreement on the pneumonics for most of the 6309 instructions, there is some
-variance with the block transfer instructions. TFM for all four variations
-seems to have gained the most traction and, thus, this is the form that is
-recommended for LWASM. However, it also supports COPY, COPY-, IMP, EXP,
-TFRP, TFRM, TFRS, and TFRR. It further adds COPY+ as a synomym for COPY,
-IMPLODE for IMP, and EXPAND for EXP.</P
-><P
->By default, LWASM accepts 6309 instructions. However, using the
-<CODE
-CLASS="PARAMETER"
->--6809</CODE
-> parameter, you can cause it to throw errors on
-6309 instructions instead.</P
-><P
->The standard addressing mode specifiers are supported. These are the
-hash sign ("#") for immediate mode, the less than sign ("&lt;") for forced
-eight bit modes, and the greater than sign ("&gt;") for forced sixteen bit modes.</P
-><P
->Additionally, LWASM supports using the asterisk ("*") to indicate
-base page addressing. This should not be used in hand-written source code,
-however, because it is non-standard and may or may not be present in future
-versions of LWASM.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x177.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->LWASM</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Source Format</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x177.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,181 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Source Format</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Dialects"
-HREF="x170.html"><LINK
-REL="NEXT"
-TITLE="Symbols"
-HREF="x187.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x170.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x187.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN177"
->3.3. Source Format</A
-></H1
-><P
->LWASM accepts plain text files in a relatively free form. It can handle
-lines terminated with CR, LF, CRLF, or LFCR which means it should be able
-to assemble files on any platform on which it compiles.</P
-><P
->Each line may start with a symbol. If a symbol is present, there must not
-be any whitespace preceding it. It is legal for a line to contain nothing
-but a symbol.</P
-><P
->The op code is separated from the symbol by whitespace. If there is
-no symbol, there must be at least one white space character preceding it.
-If applicable, the operand follows separated by whitespace. Following the
-opcode and operand is an optional comment.</P
-><P
-> It is important to note that operands cannot contain any whitespace
-except in the case of delimited strings.  This is because the first
-whitespace character will be interpreted as the separator between the
-operand column and the comment.  This behaviour is required for approximate
-source compatibility with other 6x09 assemblers.  </P
-><P
->A comment can also be introduced with a * or a ;. The comment character is
-optional for end of statement comments. However, if a symbol is the only
-thing present on the line other than the comment, the comment character is
-mandatory to prevent the assembler from interpreting the comment as an opcode.</P
-><P
->For compatibility with the output generated by some C preprocessors, LWASM
-will also ignore lines that begin with a #. This should not be used as a general
-comment character, however.</P
-><P
->The opcode is not treated case sensitively. Neither are register names in
-the operand fields. Symbols, however, are case sensitive.</P
-><P
-> As of version 2.6, LWASM supports files with line numbers.  If line
-numbers are present, the line must start with a digit.  The line number
-itself must consist only of digits.  The line number must then be followed
-by either the end of the line or exactly one white space character.  After
-that white space character, the lines are interpreted exactly as above. </P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x170.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x187.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Dialects</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Symbols</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x187.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Symbols</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Source Format"
-HREF="x177.html"><LINK
-REL="NEXT"
-TITLE="Numbers and Expressions"
-HREF="x192.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x177.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x192.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN187"
->3.4. Symbols</A
-></H1
-><P
->Symbols have no length restriction. They may contain letters, numbers, dots,
-dollar signs, and underscores. They must start with a letter, dot, or
-underscore.</P
-><P
->LWASM also supports the concept of a local symbol. A local symbol is one
-which contains either a "?" or a "@", which can appear anywhere in the symbol.
-The scope of a local symbol is determined by a number of factors. First,
-each included file gets its own local symbol scope. A blank line will also
-be considered a local scope barrier. Macros each have their own local symbol
-scope as well (which has a side effect that you cannot use a local symbol
-as an argument to a macro). There are other factors as well. In general,
-a local symbol is restricted to the block of code it is defined within.</P
-><P
->By default, unless assembling to the os9 target, a "$" in the symbol will
-also make it local.  This can be controlled by the "dollarlocal" and
-"nodollarlocal" pragmas.  In the absence of a pragma to the contrary, for
-the os9 target, a "$" in the symbol will not make it considered local while
-for all other targets it will.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x177.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x192.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Source Format</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Numbers and Expressions</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x192.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Numbers and Expressions</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Symbols"
-HREF="x187.html"><LINK
-REL="NEXT"
-TITLE="Assembler Directives"
-HREF="x200.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x187.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x200.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN192"
->3.5. Numbers and Expressions</A
-></H1
-><P
->&#13;Numbers can be expressed in binary, octal, decimal, or hexadecimal. Binary
-numbers may be prefixed with a "%" symbol or suffixed with a "b" or "B".
-Octal numbers may be prefixed with "@" or suffixed with "Q", "q", "O", or
-"o". Hexadecimal numbers may be prefixed with "$", "0x" or "0X", or suffixed
-with "H". No prefix or suffix is required for decimal numbers but they can
-be prefixed with "&amp;" if desired. Any constant which begins with a letter
-must be expressed with the correct prefix base identifier or be prefixed
-with a 0. Thus hexadecimal FF would have to be written either 0FFH or $FF.
-Numbers are not case sensitive.&#13;</P
-><P
-> A symbol may appear at any point where a number is acceptable. The
-special symbol "*" can be used to represent the starting address of the
-current source line within expressions. </P
-><P
->The ASCII value of a character can be included by prefixing it with a
-single quote ('). The ASCII values of two characters can be included by
-prefixing the characters with a quote (").</P
-><P
->&#13;LWASM supports the following basic binary operators: +, -, *, /, and %. 
-These represent addition, subtraction, multiplication, division, and
-modulus.  It also supports unary negation and unary 1's complement (- and ^
-respectively).  It is also possible to use ~ for the unary 1's complement
-operator.  For completeness, a unary positive (+) is supported though it is
-a no-op.  LWASM also supports using |, &#38;, and ^ for bitwise or, bitwise and,
-and bitwise exclusive or respectively.&#13;</P
-><P
->&#13;Operator precedence follows the usual rules. Multiplication, division, and
-modulus take precedence over addition and subtraction.  Unary operators take
-precedence over binary operators.  Bitwise operators are lower precdence
-than addition and subtraction.  To force a specific order of evaluation,
-parentheses can be used in the usual manner.&#13;</P
-><P
->&#13;As of LWASM 2.5, the operators &#38;&#38; and || are recognized for boolean and and
-boolean or respectively.  They will return either 0 or 1 (false or true). 
-They have the lowest precedence of all the binary operators.&#13;</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x187.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x200.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Symbols</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Assembler Directives</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x200.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,862 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Assembler Directives</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Numbers and Expressions"
-HREF="x192.html"><LINK
-REL="NEXT"
-TITLE="Macros"
-HREF="x491.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x192.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x491.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN200"
->3.6. Assembler Directives</A
-></H1
-><P
->Various directives can be used to control the behaviour of the
-assembler or to include non-code/data in the resulting output. Those directives
-that are not described in detail in other sections of this document are
-described below.</P
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN203"
->3.6.1. Data Directives</A
-></H2
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->FCB <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .DB <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .BYTE <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
-></DT
-><DD
-><P
->Include one or more constant bytes (separated by commas) in the output.</P
-></DD
-><DT
->FDB <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .DW <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .WORD <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
-></DT
-><DD
-><P
->Include one or more words (separated by commas) in the output.</P
-></DD
-><DT
->FQB <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .QUAD <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
->, .4BYTE <CODE
-CLASS="PARAMETER"
->expr[,...]</CODE
-></DT
-><DD
-><P
->Include one or more double words (separated by commas) in the output.</P
-></DD
-><DT
->FCC <CODE
-CLASS="PARAMETER"
->string</CODE
->, .ASCII <CODE
-CLASS="PARAMETER"
->string</CODE
->, .STR <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->Include a string of text in the output. The first character of the operand
-is the delimiter which must appear as the last character and cannot appear
-within the string. The string is included with no modifications&#62;</P
-></DD
-><DT
->FCN <CODE
-CLASS="PARAMETER"
->string</CODE
->, .ASCIZ <CODE
-CLASS="PARAMETER"
->string</CODE
->, .STRZ <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->Include a NUL terminated string of text in the output. The first character of
-the operand is the delimiter which must appear as the last character and
-cannot appear within the string. A NUL byte is automatically appended to
-the string.</P
-></DD
-><DT
->FCS <CODE
-CLASS="PARAMETER"
->string</CODE
->, .ASCIS <CODE
-CLASS="PARAMETER"
->string</CODE
->, .STRS <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->Include a string of text in the output with bit 7 of the final byte set. The
-first character of the operand is the delimiter which must appear as the last
-character and cannot appear within the string.</P
-></DD
-><DT
->ZMB <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Include a number of NUL bytes in the output. The number must be fully resolvable
-during pass 1 of assembly so no forward or external references are permitted.</P
-></DD
-><DT
->ZMD <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Include a number of zero words in the output. The number must be fully
-resolvable during pass 1 of assembly so no forward or external references are
-permitted.</P
-></DD
-><DT
->ZMQ <CODE
-CLASS="PARAMETER"
->expr<CODE
-CLASS="PARAMETER"
-></CODE
-></CODE
-></DT
-><DD
-><P
->Include a number of zero double-words in the output. The number must be fully
-resolvable during pass 1 of assembly so no forward or external references are
-permitted.</P
-></DD
-><DT
->RMB <CODE
-CLASS="PARAMETER"
->expr</CODE
->, .BLKB <CODE
-CLASS="PARAMETER"
->expr</CODE
->, .DS <CODE
-CLASS="PARAMETER"
->expr</CODE
->, .RS <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Reserve a number of bytes in the output. The number must be fully resolvable
-during pass 1 of assembly so no forward or external references are permitted.
-The value of the bytes is undefined.</P
-></DD
-><DT
->RMD <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Reserve a number of words in the output. The number must be fully
-resolvable during pass 1 of assembly so no forward or external references are
-permitted. The value of the words is undefined.</P
-></DD
-><DT
->RMQ <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Reserve a number of double-words in the output. The number must be fully
-resolvable during pass 1 of assembly so no forward or external references are
-permitted. The value of the double-words is undefined.</P
-></DD
-><DT
->INCLUDEBIN <CODE
-CLASS="PARAMETER"
->filename</CODE
-></DT
-><DD
-><P
->Treat the contents of <CODE
-CLASS="PARAMETER"
->filename</CODE
-> as a string of bytes to
-be included literally at the current assembly point. This has the same effect
-as converting the file contents to a series of FCB statements and including
-those at the current assembly point.</P
-><P
-> If <CODE
-CLASS="PARAMETER"
->filename</CODE
-> beings with a /, the file name
-will be taken as absolute.  Otherwise, the current directory will be
-searched followed by the search path in the order specified.</P
-><P
-> Please note that absolute path detection including drive letters will
-not function correctly on Windows platforms.  Non-absolute inclusion will
-work, however.</P
-></DD
-><DT
->FILL <CODE
-CLASS="PARAMETER"
->size</CODE
->,<CODE
-CLASS="PARAMETER"
->byte</CODE
-></DT
-><DD
-><P
->Insert <CODE
-CLASS="PARAMETER"
->size</CODE
-> bytes of <CODE
-CLASS="PARAMETER"
->byte</CODE
->.</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN314"
->3.6.2. Address Definition</A
-></H2
-><P
->The directives in this section all control the addresses of symbols
-or the assembly process itself.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->ORG <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Set the assembly address. The address must be fully resolvable on the
-first pass so no external or forward references are permitted. ORG is not
-permitted within sections when outputting to object files. For the DECB
-target, each ORG directive after which output is generated will cause
-a new preamble to be output. ORG is only used to determine the addresses
-of symbols when the raw target is used.</P
-></DD
-><DT
-><CODE
-CLASS="PARAMETER"
->sym</CODE
-> EQU <CODE
-CLASS="PARAMETER"
->expr</CODE
->, <CODE
-CLASS="PARAMETER"
->sym</CODE
-> = <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Define the value of <CODE
-CLASS="PARAMETER"
->sym</CODE
-> to be <CODE
-CLASS="PARAMETER"
->expr</CODE
->.</P
-></DD
-><DT
-><CODE
-CLASS="PARAMETER"
->sym</CODE
-> SET <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Define the value of <CODE
-CLASS="PARAMETER"
->sym</CODE
-> to be <CODE
-CLASS="PARAMETER"
->expr</CODE
->.
-Unlike EQU, SET permits symbols to be defined multiple times as long as SET
-is used for all instances. Use of the symbol before the first SET statement
-that sets its value is undefined.</P
-></DD
-><DT
->SETDP <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->Inform the assembler that it can assume the DP register contains
-<CODE
-CLASS="PARAMETER"
->expr</CODE
->. This directive is only advice to the assembler
-to determine whether an address is in the direct page and has no effect
-on the contents of the DP register. The value must be fully resolved during
-the first assembly pass because it affects the sizes of subsequent instructions.</P
-><P
->This directive has no effect in the object file target.</P
-></DD
-><DT
->ALIGN <CODE
-CLASS="PARAMETER"
->expr</CODE
->[,<CODE
-CLASS="PARAMETER"
->value</CODE
->]</DT
-><DD
-><P
->Force the current assembly address to be a multiple of
-<CODE
-CLASS="PARAMETER"
->expr</CODE
->.  If <CODE
-CLASS="PARAMETER"
->value</CODE
-> is not
-specified, a series of NUL bytes is output to force the alignment, if
-required.  Otherwise, the low order 8 bits of <CODE
-CLASS="PARAMETER"
->value</CODE
->
-will be used as the fill.  The alignment value must be fully resolved on the
-first pass because it affects the addresses of subsquent instructions. 
-However, <CODE
-CLASS="PARAMETER"
->value</CODE
-> may include forward references; as
-long as it resolves to a constant for the second pass, the value will be
-accepted.</P
-><P
->Unless <CODE
-CLASS="PARAMETER"
->value</CODE
-> is specified as something like $12,
-this directive is not suitable for inclusion in the middle of actual code. 
-The default padding value is $00 which is intended to be used within data
-blocks.  </P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN361"
->3.6.3. Conditional Assembly</A
-></H2
-><P
->Portions of the source code can be excluded or included based on conditions
-known at assembly time. Conditionals can be nested arbitrarily deeply. The
-directives associated with conditional assembly are described in this section.</P
-><P
->All conditionals must be fully bracketed. That is, every conditional
-statement must eventually be followed by an ENDC at the same level of nesting.</P
-><P
->Conditional expressions are only evaluated on the first assembly pass.
-It is not possible to game the assembly process by having a conditional
-change its value between assembly passes. Due to the underlying architecture
-of LWASM, there is no possible utility to IFP1 and IFP2, nor can they, as of LWASM 3.0, actually
-be implemented meaningfully. Thus there is not and never will
-be any equivalent of IFP1 or IFP2 as provided by other assemblers. Use of those opcodes
-will throw a warning and be ignored.</P
-><P
->It is important to note that if a conditional does not resolve to a constant
-during the first parsing pass, an error will be thrown. This is unavoidable because the assembler
-must make a decision about which source to include and which source to exclude at this stage.
-Thus, expressions that work normally elsewhere will not work for conditions.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->IFEQ <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to zero, the conditional
-will be considered true.</P
-></DD
-><DT
->IFNE <CODE
-CLASS="PARAMETER"
->expr</CODE
->, IF <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to a non-zero value, the conditional
-will be considered true.</P
-></DD
-><DT
->IFGT <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to a value greater than zero, the conditional
-will be considered true.</P
-></DD
-><DT
->IFGE <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to a value greater than or equal to zero, the conditional
-will be considered true.</P
-></DD
-><DT
->IFLT <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to a value less than zero, the conditional
-will be considered true.</P
-></DD
-><DT
->IFLE <CODE
-CLASS="PARAMETER"
->expr</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->expr</CODE
-> evaluates to a value less than or equal to zero , the conditional
-will be considered true.</P
-></DD
-><DT
->IFDEF <CODE
-CLASS="PARAMETER"
->sym</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->sym</CODE
-> is defined at this point in the assembly
-process, the conditional
-will be considered true.</P
-></DD
-><DT
->IFNDEF <CODE
-CLASS="PARAMETER"
->sym</CODE
-></DT
-><DD
-><P
->If <CODE
-CLASS="PARAMETER"
->sym</CODE
-> is not defined at this point in the assembly
-process, the conditional
-will be considered true.</P
-></DD
-><DT
->ELSE</DT
-><DD
-><P
->If the preceding conditional at the same level of nesting was false, the
-statements following will be assembled. If the preceding conditional at
-the same level was true, the statements following will not be assembled.
-Note that the preceding conditional might have been another ELSE statement
-although this behaviour is not guaranteed to be supported in future versions
-of LWASM.</P
-></DD
-><DT
->ENDC</DT
-><DD
-><P
->This directive marks the end of a conditional construct. Every conditional
-construct must end with an ENDC directive.</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN426"
->3.6.4. OS9 Target Directives</A
-></H2
-><P
->This section includes directives that apply solely to the OS9
-target.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->OS9 <CODE
-CLASS="PARAMETER"
->syscall</CODE
-></DT
-><DD
-><P
->&#13;This directive generates a call to the specified system call. <CODE
-CLASS="PARAMETER"
->syscall</CODE
-> may be an arbitrary expression.&#13;</P
-></DD
-><DT
->MOD <CODE
-CLASS="PARAMETER"
->size</CODE
->,<CODE
-CLASS="PARAMETER"
->name</CODE
->,<CODE
-CLASS="PARAMETER"
->type</CODE
->,<CODE
-CLASS="PARAMETER"
->flags</CODE
->,<CODE
-CLASS="PARAMETER"
->execoff</CODE
->,<CODE
-CLASS="PARAMETER"
->datasize</CODE
-></DT
-><DD
-><P
->&#13;This tells LWASM that the beginning of the actual module is here. It will
-generate a module header based on the parameters specified.  It will also
-begin calcuating the module CRC.&#13;</P
-><P
->&#13;The precise meaning of the various parameters is beyond the scope of this
-document since it is not a tutorial on OS9 module programming.&#13;</P
-></DD
-><DT
->EMOD</DT
-><DD
-><P
->&#13;This marks the end of a module and causes LWASM to emit the calculated CRC
-for the module.&#13;</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN451"
->3.6.5. Miscelaneous Directives</A
-></H2
-><P
->This section includes directives that do not fit into the other
-categories.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->INCLUDE <CODE
-CLASS="PARAMETER"
->filename</CODE
->, USE <CODE
-CLASS="PARAMETER"
->filename</CODE
-></DT
-><DD
-><P
-> Include the contents of <CODE
-CLASS="PARAMETER"
->filename</CODE
-> at
-this point in the assembly as though it were a part of the file currently
-being processed.  Note that if whitespace appears in the name of the file,
-you must enclose <CODE
-CLASS="PARAMETER"
->filename</CODE
-> in quotes.</P
-><P
->Note that the USE variation is provided only for compatibility with other
-assemblers. It is recommended to use the INCLUDE variation.</P
-><P
->If <CODE
-CLASS="PARAMETER"
->filename</CODE
-> begins with a &quot;/&quot;, it is
-interpreted as an absolute path. If it does not, the search path will be used
-to find the file. First, the directory containing the file that contains this
-directive. (Includes within an included file are relative to the included file,
-not the file that included it.) If the file is not found there, the include path
-is searched. If it is still not found, an error will be thrown. Note that the
-current directory as understood by your shell or operating system is not searched.</P
-></DD
-><DT
->END <CODE
-CLASS="PARAMETER"
->[expr]</CODE
-></DT
-><DD
-><P
->This directive causes the assembler to stop assembling immediately as though
-it ran out of input. For the DECB target only, <CODE
-CLASS="PARAMETER"
->expr</CODE
->
-can be used to set the execution address of the resulting binary. For all
-other targets, specifying <CODE
-CLASS="PARAMETER"
->expr</CODE
-> will cause an error.</P
-></DD
-><DT
->ERROR <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->Causes a custom error message to be printed at this line. This will cause
-assembly to fail. This directive is most useful inside conditional constructs
-to cause assembly to fail if some condition that is known bad happens. Everything
-from the directive to the end of the line is considered the error message.</P
-></DD
-><DT
->WARNING <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->Causes a custom warning message to be printed at this line. This will not cause
-assembly to fail. This directive is most useful inside conditional constructs
-or include files to alert the programmer to a deprecated feature being used
-or some other condition that may cause trouble later, but which may, in fact,
-not cause any trouble.</P
-></DD
-><DT
->.MODULE <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->This directive is ignored for most output targets. If the output target
-supports encoding a module name into it, <CODE
-CLASS="PARAMETER"
->string</CODE
->
-will be used as the module name.</P
-><P
->As of version 3.0, no supported output targets support this directive.</P
-></DD
-></DL
-></DIV
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x192.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x491.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Numbers and Expressions</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Macros</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x229.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,179 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Dialects</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="NEXT"
+TITLE="Source Format"
+HREF="x238.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c62.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x238.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN229"
+>3.2. Dialects</A
+></H1
+><P
+> LWASM supports all documented MC6809 instructions as defined by
+Motorola.  By default, this does not include any MC6800 compatibility
+instructions.  As of LWASM 4.11, those compatibility instructions can be
+enabled using the <CODE
+CLASS="PARAMETER"
+>--6800compat</CODE
+> option or the
+<CODE
+CLASS="PARAMETER"
+>6800compat</CODE
+> pragma.  It also supports all known HD6309
+instructions.  While there is general agreement on the pneumonics for most
+of the 6309 instructions, there is some variance with the block transfer
+instructions.  TFM for all four variations seems to have gained the most
+traction and, thus, this is the form that is recommended for LWASM. 
+However, it also supports COPY, COPY-, IMP, EXP, TFRP, TFRM, TFRS, and TFRR. 
+It further adds COPY+ as a synomym for COPY, IMPLODE for IMP, and EXPAND for
+EXP.  </P
+><P
+>By default, LWASM accepts 6309 instructions. However, using the
+<CODE
+CLASS="PARAMETER"
+>--6809</CODE
+> parameter, you can cause it to throw errors on
+6309 instructions instead.</P
+><P
+>The standard addressing mode specifiers are supported. These are the
+hash sign ("#") for immediate mode, the less than sign ("&lt;") for forced
+eight bit modes, and the greater than sign ("&gt;") for forced sixteen bit modes.</P
+><P
+>Additionally, LWASM supports using the asterisk ("*") to indicate
+base page addressing. This should not be used in hand-written source code,
+however, because it is non-standard and may or may not be present in future
+versions of LWASM.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x238.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>LWASM</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Source Format</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x238.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,181 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Source Format</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Dialects"
+HREF="x229.html"><LINK
+REL="NEXT"
+TITLE="Symbols"
+HREF="x248.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x229.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x248.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN238"
+>3.3. Source Format</A
+></H1
+><P
+>LWASM accepts plain text files in a relatively free form. It can handle
+lines terminated with CR, LF, CRLF, or LFCR which means it should be able
+to assemble files on any platform on which it compiles.</P
+><P
+>Each line may start with a symbol. If a symbol is present, there must not
+be any whitespace preceding it. It is legal for a line to contain nothing
+but a symbol.</P
+><P
+>The op code is separated from the symbol by whitespace. If there is
+no symbol, there must be at least one white space character preceding it.
+If applicable, the operand follows separated by whitespace. Following the
+opcode and operand is an optional comment.</P
+><P
+> It is important to note that operands cannot contain any whitespace
+except in the case of delimited strings.  This is because the first
+whitespace character will be interpreted as the separator between the
+operand column and the comment.  This behaviour is required for approximate
+source compatibility with other 6x09 assemblers.  </P
+><P
+>A comment can also be introduced with a * or a ;. The comment character is
+optional for end of statement comments. However, if a symbol is the only
+thing present on the line other than the comment, the comment character is
+mandatory to prevent the assembler from interpreting the comment as an opcode.</P
+><P
+>For compatibility with the output generated by some C preprocessors, LWASM
+will also ignore lines that begin with a #. This should not be used as a general
+comment character, however.</P
+><P
+>The opcode is not treated case sensitively. Neither are register names in
+the operand fields. Symbols, however, are case sensitive.</P
+><P
+> As of version 2.6, LWASM supports files with line numbers.  If line
+numbers are present, the line must start with a digit.  The line number
+itself must consist only of digits.  The line number must then be followed
+by either the end of the line or exactly one white space character.  After
+that white space character, the lines are interpreted exactly as above. </P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x229.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x248.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Dialects</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Symbols</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x24.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->DECB Binaries</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="Output Formats"
-HREF="c18.html"><LINK
-REL="PREVIOUS"
-TITLE="Output Formats"
-HREF="c18.html"><LINK
-REL="NEXT"
-TITLE="OS9 Modules"
-HREF="x29.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="c18.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 2. Output Formats</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x29.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN24"
->2.2. DECB Binaries</A
-></H1
-><P
->A DECB binary is compatible with the LOADM command in Disk Extended
-Color Basic on the CoCo. They are also compatible with CLOADM from Extended
-Color Basic. These binaries include the load address of the binary as well
-as encoding an execution address. These binaries may contain multiple loadable
-sections, each of which has its own load address.</P
-><P
->Each binary starts with a preamble. Each preamble is five bytes long. The
-first byte is zero. The next two bytes specify the number of bytes to load
-and the last two bytes specify the address to load the bytes at. Then, a
-string of bytes follows. After this string of bytes, there may be another
-preamble or a postamble. A postamble is also five bytes in length. The first
-byte of the postamble is $FF, the next two are zero, and the last two are
-the execution address for the binary.</P
-><P
->Both LWASM and LWLINK can output this format.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="c18.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x29.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Output Formats</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c18.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->OS9 Modules</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x248.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Symbols</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Source Format"
+HREF="x238.html"><LINK
+REL="NEXT"
+TITLE="Numbers and Expressions"
+HREF="x253.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x238.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x253.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN248"
+>3.4. Symbols</A
+></H1
+><P
+>Symbols have no length restriction. They may contain letters, numbers, dots,
+dollar signs, and underscores. They must start with a letter, dot, or
+underscore.</P
+><P
+>LWASM also supports the concept of a local symbol. A local symbol is one
+which contains either a "?" or a "@", which can appear anywhere in the symbol.
+The scope of a local symbol is determined by a number of factors. First,
+each included file gets its own local symbol scope. A blank line will also
+be considered a local scope barrier. Macros each have their own local symbol
+scope as well (which has a side effect that you cannot use a local symbol
+as an argument to a macro). There are other factors as well. In general,
+a local symbol is restricted to the block of code it is defined within.</P
+><P
+>By default, unless assembling to the os9 target, a "$" in the symbol will
+also make it local.  This can be controlled by the "dollarlocal" and
+"nodollarlocal" pragmas.  In the absence of a pragma to the contrary, for
+the os9 target, a "$" in the symbol will not make it considered local while
+for all other targets it will.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x238.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x253.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Source Format</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Numbers and Expressions</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x253.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,180 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Numbers and Expressions</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Symbols"
+HREF="x248.html"><LINK
+REL="NEXT"
+TITLE="Assembler Directives"
+HREF="x261.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x248.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x261.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN253"
+>3.5. Numbers and Expressions</A
+></H1
+><P
+>&#13;Numbers can be expressed in binary, octal, decimal, or hexadecimal. Binary
+numbers may be prefixed with a "%" symbol or suffixed with a "b" or "B".
+Octal numbers may be prefixed with "@" or suffixed with "Q", "q", "O", or
+"o". Hexadecimal numbers may be prefixed with "$", "0x" or "0X", or suffixed
+with "H". No prefix or suffix is required for decimal numbers but they can
+be prefixed with "&amp;" if desired. Any constant which begins with a letter
+must be expressed with the correct prefix base identifier or be prefixed
+with a 0. Thus hexadecimal FF would have to be written either 0FFH or $FF.
+Numbers are not case sensitive.&#13;</P
+><P
+> A symbol may appear at any point where a number is acceptable. The
+special symbol "*" can be used to represent the starting address of the
+current source line within expressions. </P
+><P
+>The ASCII value of a character can be included by prefixing it with a
+single quote ('). The ASCII values of two characters can be included by
+prefixing the characters with a quote (").</P
+><P
+>&#13;LWASM supports the following basic binary operators: +, -, *, /, and %. 
+These represent addition, subtraction, multiplication, division, and
+modulus.  It also supports unary negation and unary 1's complement (- and ^
+respectively).  It is also possible to use ~ for the unary 1's complement
+operator.  For completeness, a unary positive (+) is supported though it is
+a no-op.  LWASM also supports using |, &#38;, and ^ for bitwise or, bitwise and,
+and bitwise exclusive or respectively.&#13;</P
+><P
+>&#13;Operator precedence follows the usual rules. Multiplication, division, and
+modulus take precedence over addition and subtraction.  Unary operators take
+precedence over binary operators.  Bitwise operators are lower precdence
+than addition and subtraction.  To force a specific order of evaluation,
+parentheses can be used in the usual manner.&#13;</P
+><P
+>&#13;As of LWASM 2.5, the operators &#38;&#38; and || are recognized for boolean and and
+boolean or respectively.  They will return either 0 or 1 (false or true). 
+They have the lowest precedence of all the binary operators.&#13;</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x248.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x261.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Symbols</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Assembler Directives</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x261.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,884 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Assembler Directives</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Numbers and Expressions"
+HREF="x253.html"><LINK
+REL="NEXT"
+TITLE="Macros"
+HREF="x562.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x253.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x562.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN261"
+>3.6. Assembler Directives</A
+></H1
+><P
+>Various directives can be used to control the behaviour of the
+assembler or to include non-code/data in the resulting output. Those directives
+that are not described in detail in other sections of this document are
+described below.</P
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN264"
+>3.6.1. Data Directives</A
+></H2
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>FCB <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .DB <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .BYTE <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+></DT
+><DD
+><P
+>Include one or more constant bytes (separated by commas) in the output.</P
+></DD
+><DT
+>FDB <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .DW <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .WORD <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+></DT
+><DD
+><P
+>Include one or more words (separated by commas) in the output.</P
+></DD
+><DT
+>FQB <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .QUAD <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+>, .4BYTE <CODE
+CLASS="PARAMETER"
+>expr[,...]</CODE
+></DT
+><DD
+><P
+>Include one or more double words (separated by commas) in the output.</P
+></DD
+><DT
+>FCC <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .ASCII <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .STR <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>Include a string of text in the output. The first character of the operand
+is the delimiter which must appear as the last character and cannot appear
+within the string. The string is included with no modifications&#62;</P
+></DD
+><DT
+>FCN <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .ASCIZ <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .STRZ <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>Include a NUL terminated string of text in the output. The first character of
+the operand is the delimiter which must appear as the last character and
+cannot appear within the string. A NUL byte is automatically appended to
+the string.</P
+></DD
+><DT
+>FCS <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .ASCIS <CODE
+CLASS="PARAMETER"
+>string</CODE
+>, .STRS <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>Include a string of text in the output with bit 7 of the final byte set. The
+first character of the operand is the delimiter which must appear as the last
+character and cannot appear within the string.</P
+></DD
+><DT
+>ZMB <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Include a number of NUL bytes in the output. The number must be fully resolvable
+during pass 1 of assembly so no forward or external references are permitted.</P
+></DD
+><DT
+>ZMD <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Include a number of zero words in the output. The number must be fully
+resolvable during pass 1 of assembly so no forward or external references are
+permitted.</P
+></DD
+><DT
+>ZMQ <CODE
+CLASS="PARAMETER"
+>expr<CODE
+CLASS="PARAMETER"
+></CODE
+></CODE
+></DT
+><DD
+><P
+>Include a number of zero double-words in the output. The number must be fully
+resolvable during pass 1 of assembly so no forward or external references are
+permitted.</P
+></DD
+><DT
+>RMB <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>, .BLKB <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>, .DS <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>, .RS <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Reserve a number of bytes in the output. The number must be fully resolvable
+during pass 1 of assembly so no forward or external references are permitted.
+The value of the bytes is undefined.</P
+></DD
+><DT
+>RMD <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Reserve a number of words in the output. The number must be fully
+resolvable during pass 1 of assembly so no forward or external references are
+permitted. The value of the words is undefined.</P
+></DD
+><DT
+>RMQ <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Reserve a number of double-words in the output. The number must be fully
+resolvable during pass 1 of assembly so no forward or external references are
+permitted. The value of the double-words is undefined.</P
+></DD
+><DT
+>INCLUDEBIN <CODE
+CLASS="PARAMETER"
+>filename</CODE
+></DT
+><DD
+><P
+>Treat the contents of <CODE
+CLASS="PARAMETER"
+>filename</CODE
+> as a string of bytes to
+be included literally at the current assembly point. This has the same effect
+as converting the file contents to a series of FCB statements and including
+those at the current assembly point.</P
+><P
+> If <CODE
+CLASS="PARAMETER"
+>filename</CODE
+> beings with a /, the file name
+will be taken as absolute.  Otherwise, the current directory will be
+searched followed by the search path in the order specified.</P
+><P
+> Please note that absolute path detection including drive letters will
+not function correctly on Windows platforms.  Non-absolute inclusion will
+work, however.</P
+></DD
+><DT
+>FILL <CODE
+CLASS="PARAMETER"
+>byte</CODE
+>,<CODE
+CLASS="PARAMETER"
+>size</CODE
+></DT
+><DD
+><P
+>Insert <CODE
+CLASS="PARAMETER"
+>size</CODE
+> bytes of <CODE
+CLASS="PARAMETER"
+>byte</CODE
+>.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN375"
+>3.6.2. Address Definition</A
+></H2
+><P
+>The directives in this section all control the addresses of symbols
+or the assembly process itself.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>ORG <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Set the assembly address. The address must be fully resolvable on the
+first pass so no external or forward references are permitted. ORG is not
+permitted within sections when outputting to object files. For target formats
+that include address information (decb, hex, srec, and ihex), an ORG 
+directive will re-start the address sequence within the output. When using
+the raw target format, ORG is used only to determine the addresses of symbols.</P
+></DD
+><DT
+>REORG</DT
+><DD
+><P
+>Sets the assembly address to the value it had immediately prior to the
+previous ORG statement. It is used to continue assembly after some
+specification that required an additional ORG. This directive is primarily
+intended for MACRO-80c compatibility. Consider using alternatives in
+modern code.</P
+></DD
+><DT
+><CODE
+CLASS="PARAMETER"
+>sym</CODE
+> EQU <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>, <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> = <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Define the value of <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> to be <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>.</P
+></DD
+><DT
+><CODE
+CLASS="PARAMETER"
+>sym</CODE
+> SET <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Define the value of <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> to be <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>.
+Unlike EQU, SET permits symbols to be defined multiple times as long as SET
+is used for all instances. Use of the symbol before the first SET statement
+that sets its value is undefined.</P
+></DD
+><DT
+>SETDP <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>Inform the assembler that it can assume the DP register contains
+<CODE
+CLASS="PARAMETER"
+>expr</CODE
+>. This directive is only advice to the assembler
+to determine whether an address is in the direct page and has no effect
+on the contents of the DP register. The value must be fully resolved during
+the first assembly pass because it affects the sizes of subsequent instructions.</P
+><P
+>This directive has no effect in the object file target.</P
+></DD
+><DT
+>ALIGN <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>[,<CODE
+CLASS="PARAMETER"
+>value</CODE
+>]</DT
+><DD
+><P
+>Force the current assembly address to be a multiple of
+<CODE
+CLASS="PARAMETER"
+>expr</CODE
+>.  If <CODE
+CLASS="PARAMETER"
+>value</CODE
+> is not
+specified, a series of NUL bytes is output to force the alignment, if
+required.  Otherwise, the low order 8 bits of <CODE
+CLASS="PARAMETER"
+>value</CODE
+>
+will be used as the fill.  The alignment value must be fully resolved on the
+first pass because it affects the addresses of subsquent instructions. 
+However, <CODE
+CLASS="PARAMETER"
+>value</CODE
+> may include forward references; as
+long as it resolves to a constant for the second pass, the value will be
+accepted.</P
+><P
+>Unless <CODE
+CLASS="PARAMETER"
+>value</CODE
+> is specified as something like $12,
+this directive is not suitable for inclusion in the middle of actual code. 
+The default padding value is $00 which is intended to be used within data
+blocks.  </P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN426"
+>3.6.3. Conditional Assembly</A
+></H2
+><P
+>Portions of the source code can be excluded or included based on conditions
+known at assembly time. Conditionals can be nested arbitrarily deeply. The
+directives associated with conditional assembly are described in this section.</P
+><P
+>All conditionals must be fully bracketed. That is, every conditional
+statement must eventually be followed by an ENDC at the same level of nesting.</P
+><P
+>Conditional expressions are only evaluated on the first assembly pass.
+It is not possible to game the assembly process by having a conditional
+change its value between assembly passes. Due to the underlying architecture
+of LWASM, there is no possible utility to IFP1 and IFP2, nor can they, as of LWASM 3.0, actually
+be implemented meaningfully. Thus there is not and never will
+be any equivalent of IFP1 or IFP2 as provided by other assemblers. Use of those opcodes
+will throw a warning and be ignored.</P
+><P
+>It is important to note that if a conditional does not resolve to a constant
+during the first parsing pass, an error will be thrown. This is unavoidable because the assembler
+must make a decision about which source to include and which source to exclude at this stage.
+Thus, expressions that work normally elsewhere will not work for conditions.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>IFEQ <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to zero, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFNE <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>, IF <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to a non-zero value, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFGT <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to a value greater than zero, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFGE <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to a value greater than or equal to zero, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFLT <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to a value less than zero, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFLE <CODE
+CLASS="PARAMETER"
+>expr</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> evaluates to a value less than or equal to zero , the conditional
+will be considered true.</P
+></DD
+><DT
+>IFDEF <CODE
+CLASS="PARAMETER"
+>sym</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> is defined at this point in the assembly
+process, the conditional
+will be considered true.</P
+></DD
+><DT
+>IFPRAGMA <CODE
+CLASS="PARAMETER"
+>pragma</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>pragma</CODE
+> is in effect, the condition will be considered true.</P
+></DD
+><DT
+>IFNDEF <CODE
+CLASS="PARAMETER"
+>sym</CODE
+></DT
+><DD
+><P
+>If <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> is not defined at this point in the assembly
+process, the conditional
+will be considered true.</P
+></DD
+><DT
+>ELSE</DT
+><DD
+><P
+>If the preceding conditional at the same level of nesting was false, the
+statements following will be assembled. If the preceding conditional at
+the same level was true, the statements following will not be assembled.
+Note that the preceding conditional might have been another ELSE statement
+although this behaviour is not guaranteed to be supported in future versions
+of LWASM.</P
+></DD
+><DT
+>ENDC</DT
+><DD
+><P
+>This directive marks the end of a conditional construct. Every conditional
+construct must end with an ENDC directive.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN497"
+>3.6.4. OS9 Target Directives</A
+></H2
+><P
+>This section includes directives that apply solely to the OS9
+target.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>OS9 <CODE
+CLASS="PARAMETER"
+>syscall</CODE
+></DT
+><DD
+><P
+>&#13;This directive generates a call to the specified system call. <CODE
+CLASS="PARAMETER"
+>syscall</CODE
+> may be an arbitrary expression.&#13;</P
+></DD
+><DT
+>MOD <CODE
+CLASS="PARAMETER"
+>size</CODE
+>,<CODE
+CLASS="PARAMETER"
+>name</CODE
+>,<CODE
+CLASS="PARAMETER"
+>type</CODE
+>,<CODE
+CLASS="PARAMETER"
+>flags</CODE
+>,<CODE
+CLASS="PARAMETER"
+>execoff</CODE
+>,<CODE
+CLASS="PARAMETER"
+>datasize</CODE
+></DT
+><DD
+><P
+>&#13;This tells LWASM that the beginning of the actual module is here. It will
+generate a module header based on the parameters specified.  It will also
+begin calcuating the module CRC.&#13;</P
+><P
+>&#13;The precise meaning of the various parameters is beyond the scope of this
+document since it is not a tutorial on OS9 module programming.&#13;</P
+></DD
+><DT
+>EMOD</DT
+><DD
+><P
+>&#13;This marks the end of a module and causes LWASM to emit the calculated CRC
+for the module.&#13;</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="SECTION"
+><H2
+CLASS="SECTION"
+><A
+NAME="AEN522"
+>3.6.5. Miscelaneous Directives</A
+></H2
+><P
+>This section includes directives that do not fit into the other
+categories.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>INCLUDE <CODE
+CLASS="PARAMETER"
+>filename</CODE
+>, USE <CODE
+CLASS="PARAMETER"
+>filename</CODE
+></DT
+><DD
+><P
+> Include the contents of <CODE
+CLASS="PARAMETER"
+>filename</CODE
+> at
+this point in the assembly as though it were a part of the file currently
+being processed.  Note that if whitespace appears in the name of the file,
+you must enclose <CODE
+CLASS="PARAMETER"
+>filename</CODE
+> in quotes.</P
+><P
+>Note that the USE variation is provided only for compatibility with other
+assemblers. It is recommended to use the INCLUDE variation.</P
+><P
+>If <CODE
+CLASS="PARAMETER"
+>filename</CODE
+> begins with a &quot;/&quot;, it is
+interpreted as an absolute path. If it does not, the search path will be used
+to find the file. First, the directory containing the file that contains this
+directive. (Includes within an included file are relative to the included file,
+not the file that included it.) If the file is not found there, the include path
+is searched. If it is still not found, an error will be thrown. Note that the
+current directory as understood by your shell or operating system is not searched.</P
+></DD
+><DT
+>END <CODE
+CLASS="PARAMETER"
+>[expr]</CODE
+></DT
+><DD
+><P
+>This directive causes the assembler to stop assembling immediately as though
+it ran out of input. For the DECB target only, <CODE
+CLASS="PARAMETER"
+>expr</CODE
+>
+can be used to set the execution address of the resulting binary. For all
+other targets, specifying <CODE
+CLASS="PARAMETER"
+>expr</CODE
+> will cause an error.</P
+></DD
+><DT
+>ERROR <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>Causes a custom error message to be printed at this line. This will cause
+assembly to fail. This directive is most useful inside conditional constructs
+to cause assembly to fail if some condition that is known bad happens. Everything
+from the directive to the end of the line is considered the error message.</P
+></DD
+><DT
+>WARNING <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>Causes a custom warning message to be printed at this line. This will not cause
+assembly to fail. This directive is most useful inside conditional constructs
+or include files to alert the programmer to a deprecated feature being used
+or some other condition that may cause trouble later, but which may, in fact,
+not cause any trouble.</P
+></DD
+><DT
+>.MODULE <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>This directive is ignored for most output targets. If the output target
+supports encoding a module name into it, <CODE
+CLASS="PARAMETER"
+>string</CODE
+>
+will be used as the module name.</P
+><P
+>As of version 3.0, no supported output targets support this directive.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x253.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x562.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Numbers and Expressions</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Macros</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x27.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>DECB Binaries</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="NEXT"
+TITLE="ASCII Hexadecimal"
+HREF="x32.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c21.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x32.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN27"
+>2.2. DECB Binaries</A
+></H1
+><P
+>A DECB binary is compatible with the LOADM command in Disk Extended
+Color Basic on the CoCo. They are also compatible with CLOADM from Extended
+Color Basic. These binaries include the load address of the binary as well
+as encoding an execution address. These binaries may contain multiple loadable
+sections, each of which has its own load address.</P
+><P
+>Each binary starts with a preamble. Each preamble is five bytes long. The
+first byte is zero. The next two bytes specify the number of bytes to load
+and the last two bytes specify the address to load the bytes at. Then, a
+string of bytes follows. After this string of bytes, there may be another
+preamble or a postamble. A postamble is also five bytes in length. The first
+byte of the postamble is $FF, the next two are zero, and the last two are
+the execution address for the binary.</P
+><P
+>Both LWASM and LWLINK can output this format.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x32.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Output Formats</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>ASCII Hexadecimal</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x29.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->OS9 Modules</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="Output Formats"
-HREF="c18.html"><LINK
-REL="PREVIOUS"
-TITLE="DECB Binaries"
-HREF="x24.html"><LINK
-REL="NEXT"
-TITLE="Object Files"
-HREF="x37.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x24.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 2. Output Formats</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x37.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN29"
->2.3. OS9 Modules</A
-></H1
-><P
->&#13;Since version 2.5, LWASM is able to generate OS9 modules. The syntax is
-basically the same as for other assemblers.  A module starts with the MOD
-directive and ends with the EMOD directive.  The OS9 directive is provided
-as a shortcut for writing system calls.&#13;</P
-><P
->&#13;LWASM does NOT provide an OS9Defs file. You must provide your own. Also note
-that the common practice of using "ifp1" around the inclusion of the OS9Defs
-file is discouraged as it is pointless and can lead to unintentional
-problems and phasing errors.  Because LWASM reads each file exactly once,
-there is no benefit to restricting the inclusion to the first assembly pass.&#13;</P
-><P
->&#13;As of version 4.5, LWASM also implements the standard data/code address
-streams for OS9 modules.  That means that between MOD and EMOD, any RMB,
-RMD, RMQ, or equivalent directives will move the data address ahead and
-leave the code address unmodified.  Outside of an actual module, both the
-code and data addresses are moved ahead equally.  That last bit is critical
-to understand because it means any directives that follow an EMOD directive
-may have different results than other assemblers.&#13;</P
-><P
->&#13;Additionally, within a module body, the ORG directive sets only the data
-address, not the code address. However, outside a module body, ORG sets both
-addresses.&#13;</P
-><P
->Both code and data addresses are reset to 0 by the MOD directive.</P
-><P
->&#13;As of version 4.5, LWLINK also supports creation of OS9 modules.&#13;</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x24.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x37.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->DECB Binaries</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c18.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Object Files</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x32.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,157 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>ASCII Hexadecimal</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="DECB Binaries"
+HREF="x27.html"><LINK
+REL="NEXT"
+TITLE="Motorola S-Record"
+HREF="x36.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x27.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x36.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN32"
+>2.3. ASCII Hexadecimal</A
+></H1
+><P
+>This human-readable ASCII hexadecimal format consists of CR+LF terminated 
+lines of ASCII text. Each line has the following structure: a zero-padded 
+four-digit ASCII hex address, a colon separator, and one or more zero-padded
+two-digit hex values separated by commas. ASCII Hexadecimal format favors 
+paragraph-aligned addresses (i.e. a least significant address nybble value
+of zero). During output, the number of hex values on each line are adjusted
+to align the address of the next line on a paragraph boundary. The sequence 
+of addresses in the ASCII Hexadecimal file directly follows that of the source
+file; multiple ORG directives in the source code may result in out-of-sequence
+addresses in the ASCII Hexadecimal output.</P
+><P
+>LWASM can output this format since version 4.10.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x27.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x36.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>DECB Binaries</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Motorola S-Record</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x36.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,163 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Motorola S-Record</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="ASCII Hexadecimal"
+HREF="x32.html"><LINK
+REL="NEXT"
+TITLE="Intel Hex"
+HREF="x41.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x32.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x41.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN36"
+>2.4. Motorola S-Record</A
+></H1
+><P
+>This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+"S", an ASCII record type digit (0-9), a two-digit ASCII hex byte count, a 
+four-digit ASCII hex address, an optional sequence of two-digit ASCII hex data
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only S0, 
+S1, S5 and S9 record types. S1 records are limited to maximum of 16 data bytes
+in length, and  paragraph alignment of addresses is favored. The address
+sequence of the S-Records directly follows that of the source file; multiple
+ORG directives in the source code may result in out-of-sequence addresses in
+the S-Record output. </P
+><P
+>Motorola S-Record format is a standard ASCII format accepted by most memory
+device programming equipment. It is particularly useful when the assembled 
+code output is destined to reside within an EPROM or Flash memory device,
+for example.</P
+><P
+>LWASM can output this format since version 4.10. LWLINK can output this format
+since version 4.11.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x32.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x41.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>ASCII Hexadecimal</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Intel Hex</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x37.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Object Files</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="Output Formats"
-HREF="c18.html"><LINK
-REL="PREVIOUS"
-TITLE="OS9 Modules"
-HREF="x29.html"><LINK
-REL="NEXT"
-TITLE="LWASM"
-HREF="c45.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x29.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 2. Output Formats</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="c45.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN37"
->2.4. Object Files</A
-></H1
-><P
->LWASM supports generating a proprietary object file format which is
-described in <A
-HREF="c941.html"
->Chapter 6</A
->. LWLINK is then used to link these
-object files into a final binary in any of LWLINK's supported binary
-formats.</P
-><P
->Object files also support the concept of sections which are not valid
-for other output types. This allows related code from each object file
-linked to be collapsed together in the final binary.</P
-><P
->Object files are very flexible in that they allow references that are not
-known at assembly time to be resolved at link time.  However, because the
-addresses of such references are not known at assembly time, there is no way
-for the assembler to deduce that an eight bit addressing mode is possible. 
-That means the assember will default to using sixteen bit addressing
-whenever an external or cross-section reference is used.</P
-><P
->As of LWASM 2.4, it is possible to force direct page addressing for an
-external reference.  Care must be taken to ensure the resulting addresses
-are really in the direct page since the linker does not know what the direct
-page is supposed to be and does not emit errors for byte overflows.</P
-><P
->It is also possible to use external references in an eight bit immediate
-mode instruction.  In this case, only the low order eight bits will be used. 
-Again, no byte overflows will be flagged.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x29.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->OS9 Modules</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c18.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->LWASM</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x41.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,161 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Intel Hex</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="Motorola S-Record"
+HREF="x36.html"><LINK
+REL="NEXT"
+TITLE="OS9 Modules"
+HREF="x46.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x36.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN41"
+>2.5. Intel Hex</A
+></H1
+><P
+>This ASCII format consists of a series of CR+LF terminated "records" of ASCII
+text. Each record has the following structure: a start-of-record character
+":", a two-digit ASCII hex byte count, a four-digit ASCII hex address, a two-
+digit ASCII hex record type, an optional sequence of two-digit ASCII hex data 
+values, and a two-digit ASCII hex checksum. The LW tool chain issues only 00, 
+and 01 Intel Hex record types. Data records are limited to maximum of 16 
+data bytes in length, and paragraph alignment of addresses is favored. The 
+address sequence of the Intel hex records directly follows that of the source 
+file; multiple ORG directives in the source code may result in out-of-sequence 
+addresses in the Intel Hex output. </P
+><P
+>Intel Hex format is the other standard ASCII format accepted by most memory 
+device programming equipment, it and the Motorola S-Record format are used for
+similar purposes.</P
+><P
+>LWASM can output this format since version 4.10.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x36.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Motorola S-Record</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>OS9 Modules</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x46.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,171 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>OS9 Modules</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="Intel Hex"
+HREF="x41.html"><LINK
+REL="NEXT"
+TITLE="Object Files"
+HREF="x54.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x41.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x54.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN46"
+>2.6. OS9 Modules</A
+></H1
+><P
+>&#13;Since version 2.5, LWASM is able to generate OS9 modules. The syntax is
+basically the same as for other assemblers.  A module starts with the MOD
+directive and ends with the EMOD directive.  The OS9 directive is provided
+as a shortcut for writing system calls.&#13;</P
+><P
+>&#13;LWASM does NOT provide an OS9Defs file. You must provide your own. Also note
+that the common practice of using "ifp1" around the inclusion of the OS9Defs
+file is discouraged as it is pointless and can lead to unintentional
+problems and phasing errors.  Because LWASM reads each file exactly once,
+there is no benefit to restricting the inclusion to the first assembly pass.&#13;</P
+><P
+>&#13;As of version 4.5, LWASM also implements the standard data/code address
+streams for OS9 modules.  That means that between MOD and EMOD, any RMB,
+RMD, RMQ, or equivalent directives will move the data address ahead and
+leave the code address unmodified.  Outside of an actual module, both the
+code and data addresses are moved ahead equally.  That last bit is critical
+to understand because it means any directives that follow an EMOD directive
+may have different results than other assemblers.&#13;</P
+><P
+>&#13;Additionally, within a module body, the ORG directive sets only the data
+address, not the code address. However, outside a module body, ORG sets both
+addresses.&#13;</P
+><P
+>Both code and data addresses are reset to 0 by the MOD directive.</P
+><P
+>&#13;As of version 4.5, LWLINK also supports creation of OS9 modules.&#13;</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x41.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x54.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Intel Hex</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Object Files</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x491.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,234 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Macros</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Assembler Directives"
-HREF="x200.html"><LINK
-REL="NEXT"
-TITLE="Structures"
-HREF="x514.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x200.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x514.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN491"
->3.7. Macros</A
-></H1
-><P
->LWASM is a macro assembler. A macro is simply a name that stands in for a
-series of instructions. Once a macro is defined, it is used like any other
-assembler directive. Defining a macro can be considered equivalent to adding
-additional assembler directives.</P
-><P
->Macros may accept parameters. These parameters are referenced within a
-macro by the a backslash ("\") followed by a digit 1 through 9 for the first
-through ninth parameters. They may also be referenced by enclosing the
-decimal parameter number in braces ("{num}"). The special expansion "\*"
-translates to the exact parameter string, including all parameters, passed
-to the macro. These parameter references are replaced with the verbatim text
-of the parameter passed to the macro. A reference to a non-existent
-parameter will be replaced by an empty string. Macro parameters are expanded
-everywhere on each source line. That means the parameter to a macro could be
-used as a symbol or it could even appear in a comment or could cause an
-entire source line to be commented out when the macro is expanded. </P
-><P
->Parameters passed to a macro are separated by commas and the parameter list
-is terminated by any whitespace. This means that neither a comma nor whitespace
-may be included in a macro parameter.</P
-><P
->Macro expansion is done recursively. That is, within a macro, macros are
-expanded. This can lead to infinite loops in macro expansion. If the assembler
-hangs for a long time while assembling a file that uses macros, this may be
-the reason.</P
-><P
->Each macro expansion receives its own local symbol context which is not
-inherited by any macros called by it nor is it inherited from the context
-the macro was instantiated in. That means it is possible to use local symbols
-within macros without having them collide with symbols in other macros or
-outside the macro itself. However, this also means that using a local symbol
-as a parameter to a macro, while legal, will not do what it would seem to do
-as it will result in looking up the local symbol in the macro's symbol context
-rather than the enclosing context where it came from, likely yielding either
-an undefined symbol error or bizarre assembly results.</P
-><P
->Note that there is no way to define a macro as local to a symbol context. All
-macros are part of the global macro namespace. However, macros have a separate
-namespace from symbols so it is possible to have a symbol with the same name
-as a macro.</P
-><P
->Macros are defined only during the first pass. Macro expansion also
-only occurs during the first pass. On the second pass, the macro
-definition is simply ignored. Macros must be defined before they are used.</P
-><P
->The following directives are used when defining macros.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
-><CODE
-CLASS="PARAMETER"
->macroname</CODE
-> MACRO [NOEXPAND]</DT
-><DD
-><P
->This directive is used to being the definition of a macro called
-<CODE
-CLASS="PARAMETER"
->macroname</CODE
->. If <CODE
-CLASS="PARAMETER"
->macroname</CODE
-> already
-exists, it is considered an error. Attempting to define a macro within a
-macro is undefined. It may work and it may not so the behaviour should not
-be relied upon.</P
-><P
->If NOEXPAND is specified, the macro will not be expanded in a program
-listing. Instead, all bytes emitted by all instructions within the macro
-will appear to be emitted on the line where the macro is invoked, starting
-at the address of the line of the invokation. If the macro uses ORG or other
-directives that define symbols or change the assembly address, these things
-will also be hidden (except in the symbol table) and the output bytes will
-appear with incorrect address attribution. Thus, NOEXPAND should only be
-used for macros that do not mess with the assembly address or otherwise
-define symbols that should be visible.</P
-></DD
-><DT
->ENDM</DT
-><DD
-><P
->This directive indicates the end of the macro currently being defined. It
-causes the assembler to resume interpreting source lines as normal.</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x200.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x514.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Assembler Directives</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Structures</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x514.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,228 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Structures</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Macros"
-HREF="x491.html"><LINK
-REL="NEXT"
-TITLE="Object Files and Sections"
-HREF="x535.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x491.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x535.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN514"
->3.8. Structures</A
-></H1
-><P
->&#13;Structures are used to group related data in a fixed structure. A structure
-consists a number of fields, defined in sequential order and which take up
-specified size.  The assembler does not enforce any means of access within a
-structure; it assumes that whatever you are doing, you intended to do. 
-There are two pseudo ops that are used for defining structures.&#13;</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
-><CODE
-CLASS="PARAMETER"
->structname</CODE
-> STRUCT</DT
-><DD
-><P
->&#13;This directive is used to begin the definition of a structure with name
-<CODE
-CLASS="PARAMETER"
->structname</CODE
->.  Subsequent statements all form part of
-the structure definition until the end of the structure is declared.&#13;</P
-></DD
-><DT
->ENDSTRUCT, ENDS</DT
-><DD
-><P
->This directive ends the definition of the structure. ENDSTRUCT is the
-preferred form. Prior to version 3.0 of LWASM, ENDS was used to end a
-section instead of a structure.</P
-></DD
-></DL
-></DIV
-><P
->&#13;Within a structure definition, only reservation pseudo ops are permitted.
-Anything else will cause an assembly error.</P
-><P
-> Once a structure is defined, you can reserve an area of memory in the
-same structure by using the structure name as the opcode.  Structures can
-also contain fields that are themselves structures.  See the example
-below.</P
-><PRE
-CLASS="PROGRAMLISTING"
->tstruct2  STRUCT
-f1        rmb 1
-f2        rmb 1
-          ENDSTRUCT
-
-tstruct   STRUCT
-field1    rmb 2
-field2    rmb 3
-field3    tstruct2
-          ENDSTRUCT
-
-          ORG $2000
-var1      tstruct
-var2      tstruct2</PRE
-><P
->Fields are referenced using a dot (.) as a separator. To refer to the
-generic offset within a structure, use the structure name to the left of the
-dot.  If referring to a field within an actual variable, use the variable's
-symbol name to the left of the dot.</P
-><P
->You can also refer to the actual size of a structure (or a variable
-declared as a structure) using the special symbol sizeof{structname} where
-structname will be the name of the structure or the name of the
-variable.</P
-><P
->Essentially, structures are a shortcut for defining a vast number of
-symbols.  When a structure is defined, the assembler creates symbols for the
-various fields in the form structname.fieldname as well as the appropriate
-sizeof{structname} symbol.  When a variable is declared as a structure, the
-assembler does the same thing using the name of the variable.  You will see
-these symbols in the symbol table when the assembler is instructed to
-provide a listing.  For instance, the above listing will create the
-following symbols (symbol values in parentheses): tstruct2.f1 (0),
-tstruct2.f2 (1), sizeof{tstruct2} (2), tstruct.field1 (0), tstruct.field2
-(2), tstruct.field3 (5), tstruct.field3.f1 (5), tstruct.field3.f2 (6),
-sizeof{tstruct.field3} (2), sizeof{tstruct} (7), var1 {$2000}, var1.field1
-{$2000}, var1.field2 {$2002}, var1.field3 {$2005}, var1.field3.f1 {$2005},
-var1.field3.f2 {$2006}, sizeof(var1.field3} (2), sizeof{var1} (7), var2
-($2007), var2.f1 ($2007), var2.f2 ($2008), sizeof{var2} (2).  </P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x491.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x535.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Macros</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Object Files and Sections</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x535.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Object Files and Sections</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Structures"
-HREF="x514.html"><LINK
-REL="NEXT"
-TITLE="Assembler Modes and Pragmas"
-HREF="x599.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x514.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x599.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN535"
->3.9. Object Files and Sections</A
-></H1
-><P
->The object file target is very useful for large project because it allows
-multiple files to be assembled independently and then linked into the final
-binary at a later time. It allows only the small portion of the project
-that was modified to be re-assembled rather than requiring the entire set
-of source code to be available to the assembler in a single assembly process.
-This can be particularly important if there are a large number of macros,
-symbol definitions, or other metadata that uses resources at assembly time.
-By far the largest benefit, however, is keeping the source files small enough
-for a mere mortal to find things in them.</P
-><P
->With multi-file projects, there needs to be a means of resolving references to
-symbols in other source files. These are known as external references. The
-addresses of these symbols cannot be known until the linker joins all the
-object files into a single binary. This means that the assembler must be
-able to output the object code without knowing the value of the symbol. This
-places some restrictions on the code generated by the assembler. For
-example, the assembler cannot generate direct page addressing for instructions
-that reference external symbols because the address of the symbol may not
-be in the direct page. Similarly, relative branches and PC relative addressing
-cannot be used in their eight bit forms. Everything that must be resolved
-by the linker must be assembled to use the largest address size possible to
-allow the linker to fill in the correct value at link time. Note that the
-same problem applies to absolute address references as well, even those in
-the same source file, because the address is not known until link time.</P
-><P
->It is often desired in multi-file projects to have code of various types grouped
-together in the final binary generated by the linker as well. The same applies
-to data. In order for the linker to do that, the bits that are to be grouped
-must be tagged in some manner. This is where the concept of sections comes in.
-Each chunk of code or data is part of a section in the object file. Then,
-when the linker reads all the object files, it coalesces all sections of the
-same name into a single section and then considers it as a unit.</P
-><P
->The existence of sections, however, raises a problem for symbols even
-within the same source file. Thus, the assembler must treat symbols from
-different sections within the same source file in the same manner as external
-symbols. That is, it must leave them for the linker to resolve at link time,
-with all the limitations that entails.</P
-><P
->In the object file target mode, LWASM requires all source lines that
-cause bytes to be output to be inside a section. Any directives that do
-not cause any bytes to be output can appear outside of a section. This includes
-such things as EQU or RMB. Even ORG can appear outside a section. ORG, however,
-makes no sense within a section because it is the linker that determines
-the starting address of the section's code, not the assembler.</P
-><P
->All symbols defined globally in the assembly process are local to the 
-source file and cannot be exported. All symbols defined within a section are
-considered local to the source file unless otherwise explicitly exported.
-Symbols referenced from external source files must be declared external,
-either explicitly or by asking the assembler to assume that all undefined
-symbols are external.</P
-><P
->It is often handy to define a number of memory addresses that will be
-used for data at run-time but which need not be included in the binary file.
-These memory addresses are not initialized until run-time, either by the
-program itself or by the program loader, depending on the operating environment.
-Such sections are often known as BSS sections. LWASM supports generating
-sections with a BSS attribute set which causes the section definition including
-symbols exported from that section and those symbols required to resolve
-references from the local file, but with no actual code in the object file.
-It is illegal for any source lines within a BSS flagged section to cause any
-bytes to be output.</P
-><P
->The following directives apply to section handling.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->SECTION <CODE
-CLASS="PARAMETER"
->name[,flags]</CODE
->, SECT <CODE
-CLASS="PARAMETER"
->name[,flags]</CODE
->, .AREA <CODE
-CLASS="PARAMETER"
->name[,flags]</CODE
-></DT
-><DD
-><P
->Instructs the assembler that the code following this directive is to be
-considered part of the section <CODE
-CLASS="PARAMETER"
->name</CODE
->. A section name
-may appear multiple times in which case it is as though all the code from
-all the instances of that section appeared adjacent within the source file.
-However, <CODE
-CLASS="PARAMETER"
->flags</CODE
-> may only be specified on the first
-instance of the section.</P
-><P
-><CODE
-CLASS="PARAMETER"
->flags</CODE
-> is a comma separated list of flags. If a
-flag is "bss", the section will be treated as a BSS section and no
-statements that generate output are permitted.</P
-><P
->If the flag is "constant",
-the same restrictions apply as for BSS sections.  Additionally, all symbols
-defined in a constant section define absolute values and will not be
-adjusted by the linker at link time.  Constant sections cannot define
-complex expressions for symbols; the value must be fully defined at assembly
-time.  Additionally, multiple instances of a constant section do not
-coalesce into a single addressing unit; each instance starts again at offset
-0.</P
-><P
->If the section name is "bss" or ".bss" in any combination of upper and
-lower case, the section is assumed to be a BSS section. In that case,
-the flag <CODE
-CLASS="PARAMETER"
->!bss</CODE
-> can be used to override this assumption.</P
-><P
-> If the section name is "_constants" or "_constant", in any
-combination of upper and lower case, the section is assumed to be a constant
-section.  This assumption can be overridden with the "!constant"
-flag.</P
-><P
->If assembly is already happening within a section, the section is implicitly
-ended and the new section started. This is not considered an error although
-it is recommended that all sections be explicitly closed.</P
-></DD
-><DT
->ENDSECTION, ENDSECT</DT
-><DD
-><P
->This directive ends the current section. This puts assembly outside of any
-sections until the next SECTION directive. ENDSECTION is the preferred form.
-Prior to version 3.0 of LWASM, ENDS could also be used to end a section but
-as of version 3.0, it is now an alias for ENDSTRUCT instead.</P
-></DD
-><DT
-><CODE
-CLASS="PARAMETER"
->sym</CODE
-> EXTERN, <CODE
-CLASS="PARAMETER"
->sym</CODE
-> EXTERNAL, <CODE
-CLASS="PARAMETER"
->sym</CODE
-> IMPORT</DT
-><DD
-><P
->This directive defines <CODE
-CLASS="PARAMETER"
->sym</CODE
-> as an external symbol.
-This directive may occur at any point in the source code. EXTERN definitions
-are resolved on the first pass so an EXTERN definition anywhere in the
-source file is valid for the entire file. The use of this directive is
-optional when the assembler is instructed to assume that all undefined
-symbols are external. In fact, in that mode, if the symbol is referenced
-before the EXTERN directive, an error will occur.</P
-></DD
-><DT
-><CODE
-CLASS="PARAMETER"
->sym</CODE
-> EXPORT, <CODE
-CLASS="PARAMETER"
->sym</CODE
-> .GLOBL, EXPORT <CODE
-CLASS="PARAMETER"
->sym</CODE
->, .GLOBL <CODE
-CLASS="PARAMETER"
->sym</CODE
-></DT
-><DD
-><P
->This directive defines <CODE
-CLASS="PARAMETER"
->sym</CODE
-> as an exported symbol.
-This directive may occur at any point in the source code, even before the
-definition of the exported symbol.</P
-><P
->Note that <CODE
-CLASS="PARAMETER"
->sym</CODE
-> may appear as the operand or as the
-statement's symbol. If there is a symbol on the statement, that will
-take precedence over any operand that is present.</P
-></DD
-><DT
-><CODE
-CLASS="PARAMETER"
->sym</CODE
-> EXTDEP</DT
-><DD
-><P
->This directive forces an external dependency on
-<CODE
-CLASS="PARAMETER"
->sym</CODE
->, even if it is never referenced anywhere else in
-this file.</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x514.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x599.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Structures</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Assembler Modes and Pragmas</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x54.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,172 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Object Files</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="Output Formats"
+HREF="c21.html"><LINK
+REL="PREVIOUS"
+TITLE="OS9 Modules"
+HREF="x46.html"><LINK
+REL="NEXT"
+TITLE="LWASM"
+HREF="c62.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 2. Output Formats</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c62.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN54"
+>2.7. Object Files</A
+></H1
+><P
+>LWASM supports generating a proprietary object file format which is
+described in <A
+HREF="c1084.html"
+>Chapter 6</A
+>. LWLINK is then used to link these
+object files into a final binary in any of LWLINK's supported binary
+formats.</P
+><P
+>Object files also support the concept of sections which are not valid
+for other output types. This allows related code from each object file
+linked to be collapsed together in the final binary.</P
+><P
+>Object files are very flexible in that they allow references that are not
+known at assembly time to be resolved at link time.  However, because the
+addresses of such references are not known at assembly time, there is no way
+for the assembler to deduce that an eight bit addressing mode is possible. 
+That means the assember will default to using sixteen bit addressing
+whenever an external or cross-section reference is used.</P
+><P
+>As of LWASM 2.4, it is possible to force direct page addressing for an
+external reference.  Care must be taken to ensure the resulting addresses
+are really in the direct page since the linker does not know what the direct
+page is supposed to be and does not emit errors for byte overflows.</P
+><P
+>It is also possible to use external references in an eight bit immediate
+mode instruction.  In this case, only the low order eight bits will be used. 
+Again, no byte overflows will be flagged.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x46.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>OS9 Modules</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c21.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>LWASM</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x562.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,234 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Macros</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Assembler Directives"
+HREF="x261.html"><LINK
+REL="NEXT"
+TITLE="Structures"
+HREF="x585.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x261.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x585.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN562"
+>3.7. Macros</A
+></H1
+><P
+>LWASM is a macro assembler. A macro is simply a name that stands in for a
+series of instructions. Once a macro is defined, it is used like any other
+assembler directive. Defining a macro can be considered equivalent to adding
+additional assembler directives.</P
+><P
+>Macros may accept parameters. These parameters are referenced within a
+macro by the a backslash ("\") followed by a digit 1 through 9 for the first
+through ninth parameters. They may also be referenced by enclosing the
+decimal parameter number in braces ("{num}"). The special expansion "\*"
+translates to the exact parameter string, including all parameters, passed
+to the macro. These parameter references are replaced with the verbatim text
+of the parameter passed to the macro. A reference to a non-existent
+parameter will be replaced by an empty string. Macro parameters are expanded
+everywhere on each source line. That means the parameter to a macro could be
+used as a symbol or it could even appear in a comment or could cause an
+entire source line to be commented out when the macro is expanded. </P
+><P
+>Parameters passed to a macro are separated by commas and the parameter list
+is terminated by any whitespace. This means that neither a comma nor whitespace
+may be included in a macro parameter.</P
+><P
+>Macro expansion is done recursively. That is, within a macro, macros are
+expanded. This can lead to infinite loops in macro expansion. If the assembler
+hangs for a long time while assembling a file that uses macros, this may be
+the reason.</P
+><P
+>Each macro expansion receives its own local symbol context which is not
+inherited by any macros called by it nor is it inherited from the context
+the macro was instantiated in. That means it is possible to use local symbols
+within macros without having them collide with symbols in other macros or
+outside the macro itself. However, this also means that using a local symbol
+as a parameter to a macro, while legal, will not do what it would seem to do
+as it will result in looking up the local symbol in the macro's symbol context
+rather than the enclosing context where it came from, likely yielding either
+an undefined symbol error or bizarre assembly results.</P
+><P
+>Note that there is no way to define a macro as local to a symbol context. All
+macros are part of the global macro namespace. However, macros have a separate
+namespace from symbols so it is possible to have a symbol with the same name
+as a macro.</P
+><P
+>Macros are defined only during the first pass. Macro expansion also
+only occurs during the first pass. On the second pass, the macro
+definition is simply ignored. Macros must be defined before they are used.</P
+><P
+>The following directives are used when defining macros.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><CODE
+CLASS="PARAMETER"
+>macroname</CODE
+> MACRO [NOEXPAND]</DT
+><DD
+><P
+>This directive is used to being the definition of a macro called
+<CODE
+CLASS="PARAMETER"
+>macroname</CODE
+>. If <CODE
+CLASS="PARAMETER"
+>macroname</CODE
+> already
+exists, it is considered an error. Attempting to define a macro within a
+macro is undefined. It may work and it may not so the behaviour should not
+be relied upon.</P
+><P
+>If NOEXPAND is specified, the macro will not be expanded in a program
+listing. Instead, all bytes emitted by all instructions within the macro
+will appear to be emitted on the line where the macro is invoked, starting
+at the address of the line of the invokation. If the macro uses ORG or other
+directives that define symbols or change the assembly address, these things
+will also be hidden (except in the symbol table) and the output bytes will
+appear with incorrect address attribution. Thus, NOEXPAND should only be
+used for macros that do not mess with the assembly address or otherwise
+define symbols that should be visible.</P
+></DD
+><DT
+>ENDM</DT
+><DD
+><P
+>This directive indicates the end of the macro currently being defined. It
+causes the assembler to resume interpreting source lines as normal.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x261.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x585.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Assembler Directives</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Structures</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x585.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,228 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Structures</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Macros"
+HREF="x562.html"><LINK
+REL="NEXT"
+TITLE="Object Files and Sections"
+HREF="x606.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x562.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x606.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN585"
+>3.8. Structures</A
+></H1
+><P
+>&#13;Structures are used to group related data in a fixed structure. A structure
+consists a number of fields, defined in sequential order and which take up
+specified size.  The assembler does not enforce any means of access within a
+structure; it assumes that whatever you are doing, you intended to do. 
+There are two pseudo ops that are used for defining structures.&#13;</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+><CODE
+CLASS="PARAMETER"
+>structname</CODE
+> STRUCT</DT
+><DD
+><P
+>&#13;This directive is used to begin the definition of a structure with name
+<CODE
+CLASS="PARAMETER"
+>structname</CODE
+>.  Subsequent statements all form part of
+the structure definition until the end of the structure is declared.&#13;</P
+></DD
+><DT
+>ENDSTRUCT, ENDS</DT
+><DD
+><P
+>This directive ends the definition of the structure. ENDSTRUCT is the
+preferred form. Prior to version 3.0 of LWASM, ENDS was used to end a
+section instead of a structure.</P
+></DD
+></DL
+></DIV
+><P
+>&#13;Within a structure definition, only reservation pseudo ops are permitted.
+Anything else will cause an assembly error.</P
+><P
+> Once a structure is defined, you can reserve an area of memory in the
+same structure by using the structure name as the opcode.  Structures can
+also contain fields that are themselves structures.  See the example
+below.</P
+><PRE
+CLASS="PROGRAMLISTING"
+>tstruct2  STRUCT
+f1        rmb 1
+f2        rmb 1
+          ENDSTRUCT
+
+tstruct   STRUCT
+field1    rmb 2
+field2    rmb 3
+field3    tstruct2
+          ENDSTRUCT
+
+          ORG $2000
+var1      tstruct
+var2      tstruct2</PRE
+><P
+>Fields are referenced using a dot (.) as a separator. To refer to the
+generic offset within a structure, use the structure name to the left of the
+dot.  If referring to a field within an actual variable, use the variable's
+symbol name to the left of the dot.</P
+><P
+>You can also refer to the actual size of a structure (or a variable
+declared as a structure) using the special symbol sizeof{structname} where
+structname will be the name of the structure or the name of the
+variable.</P
+><P
+>Essentially, structures are a shortcut for defining a vast number of
+symbols.  When a structure is defined, the assembler creates symbols for the
+various fields in the form structname.fieldname as well as the appropriate
+sizeof{structname} symbol.  When a variable is declared as a structure, the
+assembler does the same thing using the name of the variable.  You will see
+these symbols in the symbol table when the assembler is instructed to
+provide a listing.  For instance, the above listing will create the
+following symbols (symbol values in parentheses): tstruct2.f1 (0),
+tstruct2.f2 (1), sizeof{tstruct2} (2), tstruct.field1 (0), tstruct.field2
+(2), tstruct.field3 (5), tstruct.field3.f1 (5), tstruct.field3.f2 (6),
+sizeof{tstruct.field3} (2), sizeof{tstruct} (7), var1 {$2000}, var1.field1
+{$2000}, var1.field2 {$2002}, var1.field3 {$2005}, var1.field3.f1 {$2005},
+var1.field3.f2 {$2006}, sizeof(var1.field3} (2), sizeof{var1} (7), var2
+($2007), var2.f1 ($2007), var2.f2 ($2008), sizeof{var2} (2).  </P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x562.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x606.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Macros</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Object Files and Sections</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x599.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Assembler Modes and Pragmas</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWASM"
-HREF="c45.html"><LINK
-REL="PREVIOUS"
-TITLE="Object Files and Sections"
-HREF="x535.html"><LINK
-REL="NEXT"
-TITLE="LWLINK"
-HREF="c693.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x535.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 3. LWASM</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="c693.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN599"
->3.10. Assembler Modes and Pragmas</A
-></H1
-><P
->There are a number of options that affect the way assembly is performed.
-Some of these options can only be specified on the command line because
-they determine something absolute about the assembly process. These include
-such things as the output target. Other things may be switchable during
-the assembly process. These are known as pragmas and are, by definition,
-not portable between assemblers.</P
-><P
->LWASM supports a number of pragmas that affect code generation or
-otherwise affect the behaviour of the assembler. These may be specified by
-way of a command line option or by assembler directives. The directives
-are as follows.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->PRAGMA <CODE
-CLASS="PARAMETER"
->pragma[,...]</CODE
-></DT
-><DD
-><P
->Specifies that the assembler should bring into force all <CODE
-CLASS="PARAMETER"
->pragma</CODE
->s
-specified. Any unrecognized pragma will cause an assembly error. The new
-pragmas will take effect immediately. This directive should be used when
-the program will assemble incorrectly if the pragma is ignored or not supported.</P
-></DD
-><DT
->*PRAGMA <CODE
-CLASS="PARAMETER"
->pragma[,...]</CODE
-></DT
-><DD
-><P
->This is identical to the PRAGMA directive except no error will occur with
-unrecognized or unsupported pragmas. This directive, by virtue of starting
-with a comment character, will also be ignored by assemblers that do not
-support this directive. Use this variation if the pragma is not required
-for correct functioning of the code.</P
-></DD
-><DT
->*PRAGMAPUSH <CODE
-CLASS="PARAMETER"
->pragma[,...]</CODE
-></DT
-><DD
-><P
->This directive saves the current state of the specified pragma(s) for later retrieval. See discussion below for more information.</P
-><P
->This directive will not throw any errors for any reason.</P
-></DD
-><DT
->*PRAGMAPOP <CODE
-CLASS="PARAMETER"
->pragma[,...]</CODE
-></DT
-><DD
-><P
->This directive restores the previously saved state of the specified pragma(s). See discussion below for more information.</P
-><P
->This directive will not throw any errors for any reason.</P
-></DD
-></DL
-></DIV
-><P
->Each pragma supported has a positive version and a negative version. 
-The positive version enables the pragma while the negative version disables
-it.  The negatitve version is simply the positive version with "no" prefixed
-to it.  For instance, "pragma" vs.  "nopragma".  When only one version is
-listed below, its opposite can be obtained by prepending "no" if it is not
-present or removing "no" from the beginning if it is present.</P
-><P
->Pragmas are not case sensitive.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->index0tonone</DT
-><DD
-><P
->When in force, this pragma enables an optimization affecting indexed addressing
-modes. When the offset expression in an indexed mode evaluates to zero but is
-not explicity written as 0, this will replace the operand with the equivalent
-no offset mode, thus creating slightly faster code. Because of the advantages
-of this optimization, it is enabled by default.</P
-></DD
-><DT
->cescapes</DT
-><DD
-><P
->This pragma will cause strings in the FCC, FCS, and FCN pseudo operations to
-have C-style escape sequences interpreted. The one departure from the official
-spec is that unrecognized escape sequences will return either the character
-immediately following the backslash or some undefined value. Do not rely
-on the behaviour of undefined escape sequences.</P
-></DD
-><DT
->importundefexport</DT
-><DD
-><P
->This pragma is only valid for targets that support external references. When
-in force, it will cause the EXPORT directive to act as IMPORT if the symbol
-to be exported is not defined.  This is provided for compatibility with the
-output of gcc6809 and should not be used in hand written code.  Because of
-the confusion this pragma can cause, it is disabled by default.</P
-></DD
-><DT
->undefextern</DT
-><DD
-><P
->This pragma is only valid for targets that support external references. When in
-force, if the assembler sees an undefined symbol on the second pass, it will
-automatically define it as an external symbol. This automatic definition will
-apply for the remainder of the assembly process, even if the pragma is
-subsequently turned off. Because this behaviour would be potentially surprising,
-this pragma defaults to off.</P
-><P
->The primary use for this pragma is for projects that share a large number of
-symbols between source files. In such cases, it is impractical to enumerate
-all the external references in every source file. This allows the assembler
-and linker to do the heavy lifting while not preventing a particular source
-module from defining a local symbol of the same name as an external symbol
-if it does not need the external symbol. (This pragma will not cause an
-automatic external definition if there is already a locally defined symbol.)</P
-><P
->This pragma will often be specified on the command line for large projects.
-However, depending on the specific dynamics of the project, it may be sufficient
-for one or two files to use this pragma internally.</P
-></DD
-><DT
->export</DT
-><DD
-><P
->This pragma causes all symbols to be added to the export list
-automatically.  This is useful when a large number of symbols need to be
-exported but you do not wish to include an EXPORT directive for all of them. 
-This is often useful on the command line but might be useful even inline
-with the PRAGMA directive if a large number of symbols in a row are to be
-exported.</P
-></DD
-><DT
->dollarlocal</DT
-><DD
-><P
->When set, a "$" in a symbol makes it local. When not set, "$" does not
-cause a symbol to be local.  It is set by default except when using the OS9
-target.</P
-></DD
-><DT
->dollarnotlocal</DT
-><DD
-><P
-> This is the same as the "dollarlocal" pragma except its sense is
-reversed.  That is, "dollarlocal" and "nodollarnotlocal" are equivalent and
-"nodollarlocal" and "dollarnotlocal" are equivalent.  </P
-></DD
-><DT
->pcaspcr</DT
-><DD
-><P
-> Normally, LWASM makes a distinction between PC and PCR in program
-counter relative addressing. In particular, the use of PC means an absolute
-offset from PC while PCR causes the assembler to calculate the offset to the
-specified operand and use that as the offset from PC. By setting this
-pragma, you can have PC treated the same as PCR. </P
-></DD
-><DT
->shadow</DT
-><DD
-><P
->When this pragma is in effect, it becomes possible to define a macro
-that matches an internal operation code. Thus, it makes it possible to
-redefine either CPU instructions or pseudo operations. Because this feature
-is of dubious utility, it is disabled by default.</P
-></DD
-><DT
->nolist</DT
-><DD
-><P
->Lines where this pragma is in effect will not appear in the assembly
-listing.  Also, any symbols defined under this pragma will not show up in
-the symbol list.  This is most useful in include files to avoid spamming the
-assembly listing with dozens, hundreds, or thousands of irrelevant
-symbols.</P
-></DD
-><DT
->autobranchlength</DT
-><DD
-><P
->One of the perennial annoyances for 6809 programmers is that the
-mneumonics for the short and long branch instructions are different (bxx vs. 
-lbxx), which is at odds with the rest of the instruction set.  This pragma
-is a solution to those annoying byte overflow errors that short branch
-instructions tend to aquire.</P
-><P
->When this pragma is in effect, which is not the default, whenever any
-relative branch instruction is used, its size will be automatically
-determined based on the actual distance to the destination.  In other words,
-one can write code with long or short branches everywhere and the assembler
-will choose a size for the branch.</P
-><P
->Also, while this pragma is in effect, the &#62; and &#60; symbols can be used
-to force the branch size, analogous to their use for other instructions with
-&#60; forcing 8 bit offsets and &#62; forcing 16 bit offets.</P
-><P
->Because this pragma leads to source that is incompatible with other
-assemblers, it is strongly recommended that it be invoked using the PRAGMA
-directive within the source code rather than on the command line or via the
-*PRAGMA directive.  This way, an error will be raised if someone tries to
-assemble the code under a different assembler.</P
-></DD
-><DT
->nosymbolcase, symbolnocase</DT
-><DD
-><P
->Any symbol defined while this pragma is in force will be treated as
-case insensitive, regardless whether the pragma is in force when the symbol
-is referenced.</P
-><P
->It is important to note that this pragma will not work as expected in
-all cases when using the object file assembly target.  It is intended for
-use only when the assembler will be producing the final binary.</P
-></DD
-><DT
->condundefzero</DT
-><DD
-><P
->This pragma will cause the assembler to change the way it handles
-symbols in conditional expressions.  Ordinarily, any symbol that is not
-defined prior to the conditional will throw an undefined symbol error.  With
-this pragma in effect, symbols that are not yet defined at the point the
-conditional is encountered will be treated as zero.</P
-><P
->This is not the default because it encourages poor code design. One
-should use the "IFDEF" or "IFNDEF" conditionals to test for the presence of
-a symbol.</P
-><P
->It is important to note that if a symbol is defined but it does not
-yet evaluate to a constant value at the point where the conditional appears,
-the assembler will still complain about a non constant condition.</P
-></DD
-></DL
-></DIV
-><P
->As a convenience, each input file has a pragma state stack. This
-allows, through the use of *PRAGMAPUSH and *PRAGMAPOP, a file to change a
-pragma state and then restore it to the precise state it had previously. 
-If, at the end of an input file, all pragma states have not been popped,
-they will be removed from the stack.  Thus, it is critical to employ
-*PRAGMAPOP correctly. Because each input file has its own pragma stack,
-using *PRAGMAPUSH in one file and *PRAGMAPOP in another file will not
-work.</P
-><P
->Pragma stacks are more useful in include files, in particular in
-conjunction with the nolist pragma.  One can push the state of the nolist
-pragma, engage the nolist pragma, and then pop the state of the nolist
-pragma at the end of the include file.  This will cause the entire include
-file to operate under the nolist pragma.  However, if the file is included
-while nolist is already engaged, it will not undo that state.</P
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x535.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="c693.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Object Files and Sections</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c45.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->LWLINK</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x606.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,352 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Object Files and Sections</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Structures"
+HREF="x585.html"><LINK
+REL="NEXT"
+TITLE="Assembler Modes and Pragmas"
+HREF="x670.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x585.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x670.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN606"
+>3.9. Object Files and Sections</A
+></H1
+><P
+>The object file target is very useful for large project because it allows
+multiple files to be assembled independently and then linked into the final
+binary at a later time. It allows only the small portion of the project
+that was modified to be re-assembled rather than requiring the entire set
+of source code to be available to the assembler in a single assembly process.
+This can be particularly important if there are a large number of macros,
+symbol definitions, or other metadata that uses resources at assembly time.
+By far the largest benefit, however, is keeping the source files small enough
+for a mere mortal to find things in them.</P
+><P
+>With multi-file projects, there needs to be a means of resolving references to
+symbols in other source files. These are known as external references. The
+addresses of these symbols cannot be known until the linker joins all the
+object files into a single binary. This means that the assembler must be
+able to output the object code without knowing the value of the symbol. This
+places some restrictions on the code generated by the assembler. For
+example, the assembler cannot generate direct page addressing for instructions
+that reference external symbols because the address of the symbol may not
+be in the direct page. Similarly, relative branches and PC relative addressing
+cannot be used in their eight bit forms. Everything that must be resolved
+by the linker must be assembled to use the largest address size possible to
+allow the linker to fill in the correct value at link time. Note that the
+same problem applies to absolute address references as well, even those in
+the same source file, because the address is not known until link time.</P
+><P
+>It is often desired in multi-file projects to have code of various types grouped
+together in the final binary generated by the linker as well. The same applies
+to data. In order for the linker to do that, the bits that are to be grouped
+must be tagged in some manner. This is where the concept of sections comes in.
+Each chunk of code or data is part of a section in the object file. Then,
+when the linker reads all the object files, it coalesces all sections of the
+same name into a single section and then considers it as a unit.</P
+><P
+>The existence of sections, however, raises a problem for symbols even
+within the same source file. Thus, the assembler must treat symbols from
+different sections within the same source file in the same manner as external
+symbols. That is, it must leave them for the linker to resolve at link time,
+with all the limitations that entails.</P
+><P
+>In the object file target mode, LWASM requires all source lines that
+cause bytes to be output to be inside a section. Any directives that do
+not cause any bytes to be output can appear outside of a section. This includes
+such things as EQU or RMB. Even ORG can appear outside a section. ORG, however,
+makes no sense within a section because it is the linker that determines
+the starting address of the section's code, not the assembler.</P
+><P
+>All symbols defined globally in the assembly process are local to the 
+source file and cannot be exported. All symbols defined within a section are
+considered local to the source file unless otherwise explicitly exported.
+Symbols referenced from external source files must be declared external,
+either explicitly or by asking the assembler to assume that all undefined
+symbols are external.</P
+><P
+>It is often handy to define a number of memory addresses that will be
+used for data at run-time but which need not be included in the binary file.
+These memory addresses are not initialized until run-time, either by the
+program itself or by the program loader, depending on the operating environment.
+Such sections are often known as BSS sections. LWASM supports generating
+sections with a BSS attribute set which causes the section definition including
+symbols exported from that section and those symbols required to resolve
+references from the local file, but with no actual code in the object file.
+It is illegal for any source lines within a BSS flagged section to cause any
+bytes to be output.</P
+><P
+>The following directives apply to section handling.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>SECTION <CODE
+CLASS="PARAMETER"
+>name[,flags]</CODE
+>, SECT <CODE
+CLASS="PARAMETER"
+>name[,flags]</CODE
+>, .AREA <CODE
+CLASS="PARAMETER"
+>name[,flags]</CODE
+></DT
+><DD
+><P
+>Instructs the assembler that the code following this directive is to be
+considered part of the section <CODE
+CLASS="PARAMETER"
+>name</CODE
+>. A section name
+may appear multiple times in which case it is as though all the code from
+all the instances of that section appeared adjacent within the source file.
+However, <CODE
+CLASS="PARAMETER"
+>flags</CODE
+> may only be specified on the first
+instance of the section.</P
+><P
+><CODE
+CLASS="PARAMETER"
+>flags</CODE
+> is a comma separated list of flags. If a
+flag is "bss", the section will be treated as a BSS section and no
+statements that generate output are permitted.</P
+><P
+>If the flag is "constant",
+the same restrictions apply as for BSS sections.  Additionally, all symbols
+defined in a constant section define absolute values and will not be
+adjusted by the linker at link time.  Constant sections cannot define
+complex expressions for symbols; the value must be fully defined at assembly
+time.  Additionally, multiple instances of a constant section do not
+coalesce into a single addressing unit; each instance starts again at offset
+0.</P
+><P
+>If the section name is "bss" or ".bss" in any combination of upper and
+lower case, the section is assumed to be a BSS section. In that case,
+the flag <CODE
+CLASS="PARAMETER"
+>!bss</CODE
+> can be used to override this assumption.</P
+><P
+> If the section name is "_constants" or "_constant", in any
+combination of upper and lower case, the section is assumed to be a constant
+section.  This assumption can be overridden with the "!constant"
+flag.</P
+><P
+>If assembly is already happening within a section, the section is implicitly
+ended and the new section started. This is not considered an error although
+it is recommended that all sections be explicitly closed.</P
+></DD
+><DT
+>ENDSECTION, ENDSECT</DT
+><DD
+><P
+>This directive ends the current section. This puts assembly outside of any
+sections until the next SECTION directive. ENDSECTION is the preferred form.
+Prior to version 3.0 of LWASM, ENDS could also be used to end a section but
+as of version 3.0, it is now an alias for ENDSTRUCT instead.</P
+></DD
+><DT
+><CODE
+CLASS="PARAMETER"
+>sym</CODE
+> EXTERN, <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> EXTERNAL, <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> IMPORT</DT
+><DD
+><P
+>This directive defines <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> as an external symbol.
+This directive may occur at any point in the source code. EXTERN definitions
+are resolved on the first pass so an EXTERN definition anywhere in the
+source file is valid for the entire file. The use of this directive is
+optional when the assembler is instructed to assume that all undefined
+symbols are external. In fact, in that mode, if the symbol is referenced
+before the EXTERN directive, an error will occur.</P
+></DD
+><DT
+><CODE
+CLASS="PARAMETER"
+>sym</CODE
+> EXPORT, <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> .GLOBL, EXPORT <CODE
+CLASS="PARAMETER"
+>sym</CODE
+>, .GLOBL <CODE
+CLASS="PARAMETER"
+>sym</CODE
+></DT
+><DD
+><P
+>This directive defines <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> as an exported symbol.
+This directive may occur at any point in the source code, even before the
+definition of the exported symbol.</P
+><P
+>Note that <CODE
+CLASS="PARAMETER"
+>sym</CODE
+> may appear as the operand or as the
+statement's symbol. If there is a symbol on the statement, that will
+take precedence over any operand that is present.</P
+></DD
+><DT
+><CODE
+CLASS="PARAMETER"
+>sym</CODE
+> EXTDEP</DT
+><DD
+><P
+>This directive forces an external dependency on
+<CODE
+CLASS="PARAMETER"
+>sym</CODE
+>, even if it is never referenced anywhere else in
+this file.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x585.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x670.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Structures</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Assembler Modes and Pragmas</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x670.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,575 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Assembler Modes and Pragmas</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Object Files and Sections"
+HREF="x606.html"><LINK
+REL="NEXT"
+TITLE="Convenience Instructions"
+HREF="x816.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x606.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x816.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN670"
+>3.10. Assembler Modes and Pragmas</A
+></H1
+><P
+>There are a number of options that affect the way assembly is performed.
+Some of these options can only be specified on the command line because
+they determine something absolute about the assembly process. These include
+such things as the output target. Other things may be switchable during
+the assembly process. These are known as pragmas and are, by definition,
+not portable between assemblers.</P
+><P
+>LWASM supports a number of pragmas that affect code generation or
+otherwise affect the behaviour of the assembler. These may be specified by
+way of a command line option or by assembler directives. The directives
+are as follows.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>PRAGMA <CODE
+CLASS="PARAMETER"
+>pragma[,...]</CODE
+></DT
+><DD
+><P
+>Specifies that the assembler should bring into force all <CODE
+CLASS="PARAMETER"
+>pragma</CODE
+>s
+specified. Any unrecognized pragma will cause an assembly error. The new
+pragmas will take effect immediately. This directive should be used when
+the program will assemble incorrectly if the pragma is ignored or not supported.</P
+></DD
+><DT
+>*PRAGMA <CODE
+CLASS="PARAMETER"
+>pragma[,...]</CODE
+></DT
+><DD
+><P
+>This is identical to the PRAGMA directive except no error will occur with
+unrecognized or unsupported pragmas. This directive, by virtue of starting
+with a comment character, will also be ignored by assemblers that do not
+support this directive. Use this variation if the pragma is not required
+for correct functioning of the code.</P
+></DD
+><DT
+>*PRAGMAPUSH <CODE
+CLASS="PARAMETER"
+>pragma[,...]</CODE
+></DT
+><DD
+><P
+>This directive saves the current state of the specified pragma(s) for later retrieval. See discussion below for more information.</P
+><P
+>This directive will not throw any errors for any reason.</P
+></DD
+><DT
+>*PRAGMAPOP <CODE
+CLASS="PARAMETER"
+>pragma[,...]</CODE
+></DT
+><DD
+><P
+>This directive restores the previously saved state of the specified pragma(s). See discussion below for more information.</P
+><P
+>This directive will not throw any errors for any reason.</P
+></DD
+></DL
+></DIV
+><P
+>Each pragma supported has a positive version and a negative version. 
+The positive version enables the pragma while the negative version disables
+it.  The negatitve version is simply the positive version with "no" prefixed
+to it.  For instance, "pragma" vs.  "nopragma".  When only one version is
+listed below, its opposite can be obtained by prepending "no" if it is not
+present or removing "no" from the beginning if it is present.</P
+><P
+>Pragmas are not case sensitive.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>6800compat</DT
+><DD
+><P
+>When in force, this pragma enables recognition of various
+compatibility instructions useful when assembling 6800 code.  These
+compatibility instructions are assembled into equivalent 6809 instructions. 
+This mode also includes several analogous instructions which are not
+strictly 6800 instructions but allow the similar style to be applied to 6809
+specific features.</P
+><P
+>Technically, a compliant 6809 assembler must recognize these
+instructions by default since Motorola advertised the 6809 as being source
+compatible with the 6800.  However, most source code does not require this
+compatibility and LWASM itself did not support these instructions prior to
+version 4.11 so this mode is disabled by default.</P
+></DD
+><DT
+>6809</DT
+><DD
+><P
+>This pragma allows you to mark a section of code as 6809-only. In ths mode,
+the assembler will throw an error if any 6309 instructions are used.</P
+></DD
+><DT
+>6309</DT
+><DD
+><P
+>This pragma enables the use of 6309 instructions and disables any 6809 specific
+instructions. It also changes the cycle count listing output (if selected)
+to display 6309 timings.</P
+></DD
+><DT
+>6809conv, 6309conv</DT
+><DD
+><P
+>These pragmas enable convenience instructions extending the 6809 and 6309
+instruction sets respectively. For more information, see 
+<A
+HREF="x816.html"
+>Section 3.11</A
+>.</P
+></DD
+><DT
+>index0tonone</DT
+><DD
+><P
+>When in force, this pragma enables an optimization affecting indexed addressing
+modes. When the offset expression in an indexed mode evaluates to zero but is
+not explicity written as 0, this will replace the operand with the equivalent
+no offset mode, thus creating slightly faster code. Because of the advantages
+of this optimization, it is enabled by default.</P
+></DD
+><DT
+>cescapes</DT
+><DD
+><P
+>This pragma will cause strings in the FCC, FCS, and FCN pseudo operations to
+have C-style escape sequences interpreted. The one departure from the official
+spec is that unrecognized escape sequences will return either the character
+immediately following the backslash or some undefined value. Do not rely
+on the behaviour of undefined escape sequences.</P
+></DD
+><DT
+>importundefexport</DT
+><DD
+><P
+>This pragma is only valid for targets that support external references. When
+in force, it will cause the EXPORT directive to act as IMPORT if the symbol
+to be exported is not defined.  This is provided for compatibility with the
+output of gcc6809 and should not be used in hand written code.  Because of
+the confusion this pragma can cause, it is disabled by default.</P
+></DD
+><DT
+>undefextern</DT
+><DD
+><P
+>This pragma is only valid for targets that support external references. When in
+force, if the assembler sees an undefined symbol on the second pass, it will
+automatically define it as an external symbol. This automatic definition will
+apply for the remainder of the assembly process, even if the pragma is
+subsequently turned off. Because this behaviour would be potentially surprising,
+this pragma defaults to off.</P
+><P
+>The primary use for this pragma is for projects that share a large number of
+symbols between source files. In such cases, it is impractical to enumerate
+all the external references in every source file. This allows the assembler
+and linker to do the heavy lifting while not preventing a particular source
+module from defining a local symbol of the same name as an external symbol
+if it does not need the external symbol. (This pragma will not cause an
+automatic external definition if there is already a locally defined symbol.)</P
+><P
+>This pragma will often be specified on the command line for large projects.
+However, depending on the specific dynamics of the project, it may be sufficient
+for one or two files to use this pragma internally.</P
+></DD
+><DT
+>export</DT
+><DD
+><P
+>This pragma causes all symbols to be added to the export list
+automatically.  This is useful when a large number of symbols need to be
+exported but you do not wish to include an EXPORT directive for all of them. 
+This is often useful on the command line but might be useful even inline
+with the PRAGMA directive if a large number of symbols in a row are to be
+exported.</P
+></DD
+><DT
+>dollarlocal</DT
+><DD
+><P
+>When set, a "$" in a symbol makes it local. When not set, "$" does not
+cause a symbol to be local.  It is set by default except when using the OS9
+target.</P
+></DD
+><DT
+>dollarnotlocal</DT
+><DD
+><P
+> This is the same as the "dollarlocal" pragma except its sense is
+reversed.  That is, "dollarlocal" and "nodollarnotlocal" are equivalent and
+"nodollarlocal" and "dollarnotlocal" are equivalent.  </P
+></DD
+><DT
+>pcaspcr</DT
+><DD
+><P
+> Normally, LWASM makes a distinction between PC and PCR in program
+counter relative addressing. In particular, the use of PC means an absolute
+offset from PC while PCR causes the assembler to calculate the offset to the
+specified operand and use that as the offset from PC. By setting this
+pragma, you can have PC treated the same as PCR. </P
+></DD
+><DT
+>shadow</DT
+><DD
+><P
+>When this pragma is in effect, it becomes possible to define a macro
+that matches an internal operation code. Thus, it makes it possible to
+redefine either CPU instructions or pseudo operations. Because this feature
+is of dubious utility, it is disabled by default.</P
+></DD
+><DT
+>nolist</DT
+><DD
+><P
+>Lines where this pragma is in effect will not appear in the assembly
+listing.  Also, any symbols defined under this pragma will not show up in
+the symbol list.  This is most useful in include files to avoid spamming the
+assembly listing with dozens, hundreds, or thousands of irrelevant
+symbols.</P
+></DD
+><DT
+>autobranchlength</DT
+><DD
+><P
+>One of the perennial annoyances for 6809 programmers is that the
+mneumonics for the short and long branch instructions are different (bxx vs. 
+lbxx), which is at odds with the rest of the instruction set.  This pragma
+is a solution to those annoying byte overflow errors that short branch
+instructions tend to aquire.</P
+><P
+>When this pragma is in effect, which is not the default, whenever any
+relative branch instruction is used, its size will be automatically
+determined based on the actual distance to the destination.  In other words,
+one can write code with long or short branches everywhere and the assembler
+will choose a size for the branch.</P
+><P
+>Also, while this pragma is in effect, the &#62; and &#60; symbols can be used
+to force the branch size, analogous to their use for other instructions with
+&#60; forcing 8 bit offsets and &#62; forcing 16 bit offets.</P
+><P
+>Because this pragma leads to source that is incompatible with other
+assemblers, it is strongly recommended that it be invoked using the PRAGMA
+directive within the source code rather than on the command line or via the
+*PRAGMA directive.  This way, an error will be raised if someone tries to
+assemble the code under a different assembler.</P
+></DD
+><DT
+>nosymbolcase, symbolnocase</DT
+><DD
+><P
+>Any symbol defined while this pragma is in force will be treated as
+case insensitive, regardless whether the pragma is in force when the symbol
+is referenced.</P
+><P
+>It is important to note that this pragma will not work as expected in
+all cases when using the object file assembly target.  It is intended for
+use only when the assembler will be producing the final binary.</P
+></DD
+><DT
+>condundefzero</DT
+><DD
+><P
+>This pragma will cause the assembler to change the way it handles
+symbols in conditional expressions.  Ordinarily, any symbol that is not
+defined prior to the conditional will throw an undefined symbol error.  With
+this pragma in effect, symbols that are not yet defined at the point the
+conditional is encountered will be treated as zero.</P
+><P
+>This is not the default because it encourages poor code design. One
+should use the "IFDEF" or "IFNDEF" conditionals to test for the presence of
+a symbol.</P
+><P
+>It is important to note that if a symbol is defined but it does not
+yet evaluate to a constant value at the point where the conditional appears,
+the assembler will still complain about a non constant condition.</P
+></DD
+><DT
+>forwardrefmax</DT
+><DD
+><P
+>This pragma will disable forward reference optimization completely.
+Ordinarily, LWASM will attempt to select the shortest possible addressing
+mode for forward references.  However, in many source files, especially
+those not using the PCR relative addressing modes, this optimization is
+pointless since the assembler will almost certainly settle on a 16 bit
+offset or address.  If all variables in the direct page are defined before
+the main body of the code, the benefit of forward reference optimization
+almost certainly vanishes completely.  However, the cost of doing that
+optimization remains and can result in a very long assembly time.</P
+><P
+>Enabling this pragma will cause all forward references to use the
+maximum offset or address size, much the same has EDTASM and other pure
+two pass assemblers do. The side effect is that all line lengths and
+symbol values are fully resolved after the initial parsing pass and the
+amount of work to resolve everything becomes almost nil.</P
+><P
+>While this pragma can be applied selectively to sections of source
+code (use *PRAGMA if doing so and compatibility with other assemblers
+is desired), it is likely more useful when provided as a command line
+pragma.</P
+><P
+>It should be noted that the presence or absence of this pragma
+will not change the correctness of the generated code unless cycle counts
+or byte counts are critical (which they usually are not). It also will
+not override the operand size override prefixes (&lt; and &gt;). It only
+applies when the assembler is left to guess what the operand size is.</P
+></DD
+><DT
+>operandsizewarning</DT
+><DD
+><P
+>Enabling this pragma will cause LWASM to show a warning when it
+detects that a smaller addressing mode could be used for an instruction.
+This is particularly useful for finding places where long branches are used
+where short branches could be used instead. It will also show the warnings
+for indexing offsets (regardless of whether the operand size is
+forced).</P
+><P
+>As of LWASM 4.16, no other checks are performed.</P
+></DD
+><DT
+>qrts</DT
+><DD
+><P
+>&#13;Enables the use of the ?RTS branch target. ?RTS is implemented to maintain
+compatibility with the MACRO-80c assembler.  It works by searching backward
+in the code for an RTS instruction.  If none is found, it inverts the branch
+logic and inserts an RTS following the branch instruction.  Below you can
+see how a BMI (2B xx) has been assembled as a BPL *+1 (2A 01) to skip over an
+inserted RTS (39).</P
+><PRE
+CLASS="PROGRAMLISTING"
+>1D1E 7D1D1D            TST   WHICH1
+1D21 2A0139            BMI   ?RTS
+1D24 BD1D65            JSR   INV</PRE
+></DD
+><DT
+>m80ext</DT
+><DD
+><P
+>&#13;This pragma (along with pragma qrts) enables some uncommon behaviors to
+accomodate The Micro Works MACRO-80c assembler from 1982.  This assembler
+was used by a number of notable TRS-80 Color Computer applications and the
+goal of this pragma is to allow them to build identical binaries from
+unmodified, vintage source code.</P
+><P
+>&#13;In m80ext mode, the handling of the "END" pseudo-op changes when used inside
+an include file.  Instead of terminating all assembly, it merely stops
+processing of the current include file (this behavior matches the original
+Motorola 6809 assembler).  In addition, loading an ASCII value with a single
+quote (e.g., LDA #'N) is extended to 16-bit registers (e.g., LDD #'NO). 
+LWASM normally supports this via double quote and that is the proper use in
+modern code.  Finally, the FCC pseudo-op is extended to handle FCB-like
+behavior after the closing delimiter:</P
+><PRE
+CLASS="PROGRAMLISTING"
+>                       FCC "Greetings from 1982",13,0</PRE
+></DD
+><DT
+>testmode</DT
+><DD
+><P
+>&#13;This pragma is intended for internal testing purposes. In testmode, the
+assembler searches for a specially-formatted comment starting with a
+semicolon followed by a period.  Immediately afterward are a list of hex
+bytes that the assembler is expected to generate.  Likewise, if the
+assembler is expected to throw an error or warning on a given line, you can
+check by specifying "E:" followed by the error number.  In this case the
+error is ignored and the assembler continues ignoring the line in question.&#13;</P
+><PRE
+CLASS="PROGRAMLISTING"
+>1D1E 7D1D1D            TST   WHICH1    ;.7d1d1d
+1D21 2A0139            BMI   ?RTS      ;.2a0139
+1D24 1D24              FDB   *         ;.1d24
+1D26                   xyz   INV       ;.E:32    (Error 32 is "Bad opcode")</PRE
+></DD
+><DT
+>emuext</DT
+><DD
+><P
+>&#13;This pragma enables two instructions useful when running code in compatible
+emulators. Break breaks into the debugger. Log writes printf-style
+output to the debug window&#13;</P
+><PRE
+CLASS="PROGRAMLISTING"
+>      LOG           ; log output
+      FDB   FSTR    ; pointer to format string
+      FDB   PX1     ; 16 bit pointer to 16 bit value
+      FDB   PY1     ; 16 bit pointer to 8 bit value (see format string!)
+      FDB   PX2     ; 16 bit pointer to 16 bit value
+      FDB   PY2     ; 16 bit pointer to 8 bit value
+      ; execution continues here ...
+      RTS
+
+; format string
+FSTR  FCC   "%hu,%hhu - %hu,%hhu"
+      FCB   10,0</PRE
+></DD
+></DL
+></DIV
+><P
+>As a convenience, each input file has a pragma state stack. This
+allows, through the use of *PRAGMAPUSH and *PRAGMAPOP, a file to change a
+pragma state and then restore it to the precise state it had previously. 
+If, at the end of an input file, all pragma states have not been popped,
+they will be removed from the stack.  Thus, it is critical to employ
+*PRAGMAPOP correctly. Because each input file has its own pragma stack,
+using *PRAGMAPUSH in one file and *PRAGMAPOP in another file will not
+work.</P
+><P
+>Pragma stacks are more useful in include files, in particular in
+conjunction with the nolist pragma.  One can push the state of the nolist
+pragma, engage the nolist pragma, and then pop the state of the nolist
+pragma at the end of the include file.  This will cause the entire include
+file to operate under the nolist pragma.  However, if the file is included
+while nolist is already engaged, it will not undo that state.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x606.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x816.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Object Files and Sections</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Convenience Instructions</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x793.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Linker Operation</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWLINK"
-HREF="c693.html"><LINK
-REL="PREVIOUS"
-TITLE="LWLINK"
-HREF="c693.html"><LINK
-REL="NEXT"
-TITLE="Linking Scripts"
-HREF="x807.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="c693.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 4. LWLINK</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x807.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN793"
->4.2. Linker Operation</A
-></H1
-><P
->&#13;LWLINK takes one or more files in supported input formats and links them
-into a single binary. Currently supported formats are the LWTOOLS object
-file format and the archive format used by LWAR. While the precise method is
-slightly different, linking can be conceptualized as the following steps.&#13;</P
-><P
-></P
-><OL
-TYPE="1"
-><LI
-><P
->First, the linker loads a linking script. If no script is specified, it
-loads a built-in default script based on the output format selected. This
-script tells the linker how to lay out the various sections in the final
-binary.</P
-></LI
-><LI
-><P
->Next, the linker reads all the input files into memory. At this time, it
-flags any format errors in those files. It constructs a table of symbols
-for each object at this time.</P
-></LI
-><LI
-><P
->The linker then proceeds with organizing the sections loaded from each file
-according to the linking script. As it does so, it is able to assign addresses
-to each symbol defined in each object file. At this time, the linker may
-also collapse different instances of the same section name into a single
-section by appending the data from each subsequent instance of the section
-to the first instance of the section.</P
-></LI
-><LI
-><P
->Next, the linker looks through every object file for every incomplete reference.
-It then attempts to fully resolve that reference. If it cannot do so, it
-throws an error. Once a reference is resolved, the value is placed into
-the binary code at the specified section. It should be noted that an
-incomplete reference can reference either a symbol internal to the object
-file or an external symbol which is in the export list of another object
-file.</P
-></LI
-><LI
-><P
->If all of the above steps are successful, the linker opens the output file
-and actually constructs the binary.</P
-></LI
-></OL
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="c693.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x807.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->LWLINK</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c693.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Linking Scripts</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- a/docs/manual/x807.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,313 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Linking Scripts</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWLINK"
-HREF="c693.html"><LINK
-REL="PREVIOUS"
-TITLE="Linker Operation"
-HREF="x793.html"><LINK
-REL="NEXT"
-TITLE="Format Specific Linking Notes"
-HREF="x864.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x793.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 4. LWLINK</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="x864.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN807"
->4.3. Linking Scripts</A
-></H1
-><P
->A linker script is used to instruct the linker about how to assemble the
-various sections into a completed binary. It consists of a series of
-directives which are considered in the order they are encountered.</P
-><P
->The sections will appear in the resulting binary in the order they are
-specified in the script file. If a referenced section is not found, the linker will behave as though the
-section did exist but had a zero size, no relocations, and no exports.
-A section should only be referenced once. Any subsequent references will have
-an undefined effect.</P
-><P
->All numbers are in linking scripts are specified in hexadecimal. All directives
-are case sensitive although the hexadecimal numbers are not.</P
-><P
->A section name can be specified as a "*", then any section not
-already matched by the script will be matched. The "*" can be followed
-by a comma and a flag to narrow the section down slightly, also.
-If the flag is "!bss", then any section that is not flagged as a bss section
-will be matched. If the flag is "bss", then any section that is flagged as
-bss will be matched.</P
-><P
->The following directives are understood in a linker script.</P
-><P
-></P
-><DIV
-CLASS="VARIABLELIST"
-><DL
-><DT
->sectopt <CODE
-CLASS="PARAMETER"
->section</CODE
-> padafter <CODE
-CLASS="PARAMETER"
->byte,...</CODE
-></DT
-><DD
-><P
->&#13;This will cause the linker to append the specified list of byte values
-(specified in hexadecimal separated by commas) to the end of the named
-section.  This is done once all instances of the specified section are
-collected together.  This has no effect if the specified section does not
-appear anywhere in any of the objects specified for linking. &#13;</P
-><P
->&#13;If code depends on the presence of this padding somewhere, it is sufficient
-to include an empty section of the specified name in the object that depends
-on it.&#13;</P
-></DD
-><DT
->define basesympat <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->&#13;This causes the linker to define a symbol for the ultimate base address of
-each section using the pattern specified by <CODE
-CLASS="PARAMETER"
->string</CODE
->. 
-In the string, %s can appear exactly once and will be replaced with the
-section name.  The base address is calculated after all instances of each
-section have been collapsed together.&#13;</P
-><P
->&#13;It should be noted that if none of the objects to be linked contains a
-particular section name, there will be no base symbol defined for it, even
-if it is listed explicitly in the link script.  If code depends on the
-presence of these symbols, it is sufficient to include an empty section of
-the specified name in the object that depends on it.&#13;</P
-><P
->  If the pattern resolves to the same string for multiple
-sections, the results are undefined.&#13;</P
-></DD
-><DT
->define lensympat <CODE
-CLASS="PARAMETER"
->string</CODE
-></DT
-><DD
-><P
->&#13;This causes the linker to define a symbol for the ultimate length of each
-section using the pattern specified by <CODE
-CLASS="PARAMETER"
->string</CODE
->.  In
-the string, %s can appear exactly once and will be replaced with the section
-name.  The length is calculated after all instances of a section have been
-collapsed together.&#13;</P
-><P
->&#13;It should be noted that if none of the objects to be linked contains a
-particular section name, there will be no length symbol defined for it, even
-if it is listed explicitly in the link script.  If code depends on the
-presence of these symbols, it is sufficient to include an empty section of
-the specified name in the object that depends on it.&#13;</P
-><P
->If the pattern resolves to the same string for multiple
-sections, the results are undefined.&#13;</P
-></DD
-><DT
->section <CODE
-CLASS="PARAMETER"
->name</CODE
-> load <CODE
-CLASS="PARAMETER"
->addr</CODE
-></DT
-><DD
-><P
->&#13;This causes the section <CODE
-CLASS="PARAMETER"
->name</CODE
-> to load at
-<CODE
-CLASS="PARAMETER"
->addr</CODE
->. For the raw target, only one "load at" entry is
-allowed for non-bss sections and it must be the first one. For raw targets,
-it affects the addresses the linker assigns to symbols but has no other
-affect on the output. bss sections may all have separate load addresses but
-since they will not appear in the binary anyway, this is okay.</P
-><P
->For the decb target, each "load" entry will cause a new "block" to be
-output to the binary which will contain the load address. It is legal for
-sections to overlap in this manner - the linker assumes the loader will sort
-everything out.</P
-></DD
-><DT
->section <CODE
-CLASS="PARAMETER"
->name</CODE
-></DT
-><DD
-><P
->&#13;This will cause the section <CODE
-CLASS="PARAMETER"
->name</CODE
-> to load after the previously listed
-section.</P
-></DD
-><DT
->entry <CODE
-CLASS="PARAMETER"
->addr or sym</CODE
-></DT
-><DD
-><P
->This will cause the execution address (entry point) to be the address
-specified (in hex) or the specified symbol name. The symbol name must
-match a symbol that is exported by one of the object files being linked.
-This has no effect for targets that do not encode the entry point into the
-resulting file. If not specified, the entry point is assumed to be address 0
-which is probably not what you want. The default link scripts for targets
-that support this directive automatically starts at the beginning of the
-first section (usually "init" or "code") that is emitted in the binary.</P
-></DD
-><DT
->pad <CODE
-CLASS="PARAMETER"
->size</CODE
-></DT
-><DD
-><P
->This will cause the output file to be padded with NUL bytes to be exactly
-<CODE
-CLASS="PARAMETER"
->size</CODE
-> bytes in length. This only makes sense for a raw target.</P
-></DD
-></DL
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x793.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="x864.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Linker Operation</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c693.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Format Specific Linking Notes</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x816.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,160 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Convenience Instructions</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Assembler Modes and Pragmas"
+HREF="x670.html"><LINK
+REL="NEXT"
+TITLE="Cycle Counts"
+HREF="x821.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x670.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x821.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="CONVINST"
+>3.11. Convenience Instructions</A
+></H1
+><P
+>&#13;Similar to the 6800 compatibility instructions (pragma 6800compat) these
+pragma 6809conv and pragma 6309conv enable convenience extensions to the
+6809 and 6309 instruction set.  Originally intended for compatibility with
+the MACRO-80c assembler, these have proven useful in large codebases that
+target both the 6809 and the 6309.</P
+><P
+>&#13;The 6809 extensions are straightforward with the exception of "TSTD" which
+assembles as "STD -2,S".  A benefit of using these is they will "just work"
+and take on their 6309 equivalent when you enable 6309 assembly mode. 
+Supported instructions: ASRD, CLRD,   COMD,   LSLD,   LSRD,   NEGD,   TSTD.</P
+><P
+>&#13;6309 extensions are based on common patterns described by Chris Burke and
+Darren Atkinson in their 6309 documentation and include the following
+instructions: ASRQ,   CLRQ,   COMQ,   LSLE,   LSLF,   LSLQ,   LSRQ,   NEGE,
+   NEGF,   NEGW,   NEGQ,   TSTQ.</P
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x670.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x821.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Assembler Modes and Pragmas</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Cycle Counts</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x821.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,174 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Cycle Counts</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWASM"
+HREF="c62.html"><LINK
+REL="PREVIOUS"
+TITLE="Convenience Instructions"
+HREF="x816.html"><LINK
+REL="NEXT"
+TITLE="LWLINK"
+HREF="c827.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x816.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 3. LWASM</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="c827.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN821"
+>3.12. Cycle Counts</A
+></H1
+><P
+>&#13;The following options for displaying cycle counts in listings are provided.
+These options are enabled from pragmas on the command line or in the
+assembly files themselves.  For compatibility with other assemblers you can
+use the "OPT" keyword in addition to "PRAGMA."</P
+><PRE
+CLASS="PROGRAMLISTING"
+>opt c  - enable cycle counts: [8]
+opt cd - enable detailed cycle counts breaking down addressing modes: [5+3]
+opt ct - show a running subtotal of cycles
+opt cc - clear the running subtotal</PRE
+><P
+>&#13;The assembler supports both 6809 as well as native-mode 6309 cycle counts.
+In 6309 mode the counts are displayed in parenthesis instead of brackets. 
+In addition, some operations have a variable cycle count.  In this case a
+"+?" is displayed to alert the reader.  Sample output is shown below.</P
+><PRE
+CLASS="PROGRAMLISTING"
+>266f 7d25e2     (window.asm):00313 [7]     7       move   tst   putflg
+2672 2602       (window.asm):00314 [5]     12             bne   a@
+2674 1e13       (window.asm):00315 [8]     20             exg   x,u
+2676 0dd6       (window.asm):00316 [6]     26      a@     tst   is6309
+2678 2618       (window.asm):00317 [5]     31             bne   exit@
+                (window.asm):00318                        opt   6309
+267a 10860085   (window.asm):00319 (4)     35      b@     ldw   #133
+267e 113813     (window.asm):00320 (6+?)   41             tfm   x+,u+
+2681 30881b     (window.asm):00321 (4+1)   46             leax  27,x
+2684 33c81b     (window.asm):00322 (4+1)   51             leau  27,u
+2687 4a         (window.asm):00323 (1)     52             deca
+2688 26f0       (window.asm):00324 (5)     57             bne   b@</PRE
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x816.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="c827.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Convenience Instructions</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c62.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>LWLINK</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/docs/manual/x864.html	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
-<HTML
-><HEAD
-><TITLE
->Format Specific Linking Notes</TITLE
-><META
-NAME="GENERATOR"
-CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
-REL="HOME"
-TITLE="LW Tool Chain"
-HREF="index.html"><LINK
-REL="UP"
-TITLE="LWLINK"
-HREF="c693.html"><LINK
-REL="PREVIOUS"
-TITLE="Linking Scripts"
-HREF="x807.html"><LINK
-REL="NEXT"
-TITLE="Libraries and LWAR"
-HREF="c879.html"></HEAD
-><BODY
-CLASS="SECTION"
-BGCOLOR="#FFFFFF"
-TEXT="#000000"
-LINK="#0000FF"
-VLINK="#840084"
-ALINK="#0000FF"
-><DIV
-CLASS="NAVHEADER"
-><TABLE
-SUMMARY="Header navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TH
-COLSPAN="3"
-ALIGN="center"
->LW Tool Chain</TH
-></TR
-><TR
-><TD
-WIDTH="10%"
-ALIGN="left"
-VALIGN="bottom"
-><A
-HREF="x807.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="80%"
-ALIGN="center"
-VALIGN="bottom"
->Chapter 4. LWLINK</TD
-><TD
-WIDTH="10%"
-ALIGN="right"
-VALIGN="bottom"
-><A
-HREF="c879.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-></TABLE
-><HR
-ALIGN="LEFT"
-WIDTH="100%"></DIV
-><DIV
-CLASS="SECTION"
-><H1
-CLASS="SECTION"
-><A
-NAME="AEN864"
->4.4. Format Specific Linking Notes</A
-></H1
-><P
->Some formats require special information to be able to generate actual
-binaries.  If the specific format you are interested in is not listed in
-this section, then there is nothing special you need to know about to create
-a final binary.</P
-><DIV
-CLASS="SECTION"
-><H2
-CLASS="SECTION"
-><A
-NAME="AEN867"
->4.4.1. OS9 Modules</A
-></H2
-><P
->OS9 modules need to embed several items into the module header. These
-items are the type of module, the langauge of the module, the module
-attributes, the module revision number, the data size (bss), and the
-execution offset.  These are all either calculated or default to reasonable
-values.</P
-><P
->The data size is calcuated as the sum of all sections named "bss" or
-".bss" in all object files that are linked together.</P
-><P
->The execution offset is calculated from the address of the special
-symbol "__start" which must be an exported (external) symbol in one of the
-objects to be linked.</P
-><P
->The type defaults to "Prgrm" or "Program module". The language
-defaults to "Objct" or "6809 object code".  Attributes default to enabling
-the re-entrant flag.  And finally, the revision defaults to zero.</P
-><P
->The embedded module name is the output filename. If the output
-filename includes more than just the filename, this will probably not be
-what you want.</P
-><P
->The type, language, attributes, revision, and module name can all be
-overridden by providing a special section in exactly one of the object files
-to be linked.  This section is called "__os9" (note the two underscores). 
-To override the type, language, attributes, or revision values, define a
-non-exported symbol in this section called "type", "lang", "attr", or "rev"
-respectively.  Any other symbols defined are ignored.  To override the
-module name, include as the only actual code in the section a NUL terminated
-string (the FCN directive is useful for this).  If there is no code in the
-section or it beings with a NUL, the default name will be used.  Any of the
-preceeding that are not defined in the special section will retain their
-default values.</P
-><P
->The built-in link script for OS9 modules will place the following
-sections, in order, in the module: "code", ".text", "data", ".data".  It
-will merge all sections with the name "bss" or ".bss" into the "data"
-section.  All other section names are ignored.  What this means is that you
-must define your data variables in the a section called "bss" or ".bss" even
-though you will be refencing them all as offsets from U.  This does have the
-unpleasant side effect that all BSS references will end up being 16 bit
-offsets because the assembler cannot know what the offset will be once the
-linker is finished its work.  Thus, if the tightest possible code is
-required, having LWASM directly output the module is a better choice.</P
-><P
->While the built-in link script is probably sufficient for most
-purposes, you can provide your own script.  If you provide a custom link
-script, you must start your code and data sections at location 000D to
-accommodate the module header.  Otherwise, you will have an incorrect
-location for the execution offset.  You must use the ENTRY directive in the
-script to define the entry point for the module.</P
-><P
->It should also be obvious from the above that you cannot mix the bss
-(rmb) definitions with the module code when linking separately.  Those
-familiar with typical module creation will probably find this an unpleasant
-difference but it is unavoidable.</P
-><P
->It should also be noted that direct page references should also be
-avoided because you cannot know ahead of time whether the linker is going to
-end up putting a particular variable in the first 256 bytes of the module's
-data space.  If, however, you know for certain you will have less than 256
-bytes of defined data space across all of the object files that will be
-linked, you can instead use forced DP addressing for your data addresses
-instead of the ,u notation.  When linking with 3rd party libraries, this
-practice should be avoided.  Also, when creating libraries, always use the
-offset from U technique.</P
-></DIV
-></DIV
-><DIV
-CLASS="NAVFOOTER"
-><HR
-ALIGN="LEFT"
-WIDTH="100%"><TABLE
-SUMMARY="Footer navigation table"
-WIDTH="100%"
-BORDER="0"
-CELLPADDING="0"
-CELLSPACING="0"
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
-><A
-HREF="x807.html"
-ACCESSKEY="P"
->Prev</A
-></TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="index.html"
-ACCESSKEY="H"
->Home</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
-><A
-HREF="c879.html"
-ACCESSKEY="N"
->Next</A
-></TD
-></TR
-><TR
-><TD
-WIDTH="33%"
-ALIGN="left"
-VALIGN="top"
->Linking Scripts</TD
-><TD
-WIDTH="34%"
-ALIGN="center"
-VALIGN="top"
-><A
-HREF="c693.html"
-ACCESSKEY="U"
->Up</A
-></TD
-><TD
-WIDTH="33%"
-ALIGN="right"
-VALIGN="top"
->Libraries and LWAR</TD
-></TR
-></TABLE
-></DIV
-></BODY
-></HTML
->
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x927.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,191 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linker Operation</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWLINK"
+HREF="c827.html"><LINK
+REL="PREVIOUS"
+TITLE="LWLINK"
+HREF="c827.html"><LINK
+REL="NEXT"
+TITLE="Linking Scripts"
+HREF="x941.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="c827.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 4. LWLINK</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x941.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN927"
+>4.2. Linker Operation</A
+></H1
+><P
+>&#13;LWLINK takes one or more files in supported input formats and links them
+into a single binary. Currently supported formats are the LWTOOLS object
+file format and the archive format used by LWAR. While the precise method is
+slightly different, linking can be conceptualized as the following steps.&#13;</P
+><P
+></P
+><OL
+TYPE="1"
+><LI
+><P
+>First, the linker loads a linking script. If no script is specified, it
+loads a built-in default script based on the output format selected. This
+script tells the linker how to lay out the various sections in the final
+binary.</P
+></LI
+><LI
+><P
+>Next, the linker reads all the input files into memory. At this time, it
+flags any format errors in those files. It constructs a table of symbols
+for each object at this time.</P
+></LI
+><LI
+><P
+>The linker then proceeds with organizing the sections loaded from each file
+according to the linking script. As it does so, it is able to assign addresses
+to each symbol defined in each object file. At this time, the linker may
+also collapse different instances of the same section name into a single
+section by appending the data from each subsequent instance of the section
+to the first instance of the section.</P
+></LI
+><LI
+><P
+>Next, the linker looks through every object file for every incomplete reference.
+It then attempts to fully resolve that reference. If it cannot do so, it
+throws an error. Once a reference is resolved, the value is placed into
+the binary code at the specified section. It should be noted that an
+incomplete reference can reference either a symbol internal to the object
+file or an external symbol which is in the export list of another object
+file.</P
+></LI
+><LI
+><P
+>If all of the above steps are successful, the linker opens the output file
+and actually constructs the binary.</P
+></LI
+></OL
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="c827.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x941.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>LWLINK</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c827.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Linking Scripts</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/manual/x941.html	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,339 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
+<HTML
+><HEAD
+><TITLE
+>Linking Scripts</TITLE
+><META
+NAME="GENERATOR"
+CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
+REL="HOME"
+TITLE="LW Tool Chain"
+HREF="index.html"><LINK
+REL="UP"
+TITLE="LWLINK"
+HREF="c827.html"><LINK
+REL="PREVIOUS"
+TITLE="Linker Operation"
+HREF="x927.html"><LINK
+REL="NEXT"
+TITLE="Format Specific Linking Notes"
+HREF="x1007.html"></HEAD
+><BODY
+CLASS="SECTION"
+BGCOLOR="#FFFFFF"
+TEXT="#000000"
+LINK="#0000FF"
+VLINK="#840084"
+ALINK="#0000FF"
+><DIV
+CLASS="NAVHEADER"
+><TABLE
+SUMMARY="Header navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TH
+COLSPAN="3"
+ALIGN="center"
+>LW Tool Chain</TH
+></TR
+><TR
+><TD
+WIDTH="10%"
+ALIGN="left"
+VALIGN="bottom"
+><A
+HREF="x927.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="80%"
+ALIGN="center"
+VALIGN="bottom"
+>Chapter 4. LWLINK</TD
+><TD
+WIDTH="10%"
+ALIGN="right"
+VALIGN="bottom"
+><A
+HREF="x1007.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+></TABLE
+><HR
+ALIGN="LEFT"
+WIDTH="100%"></DIV
+><DIV
+CLASS="SECTION"
+><H1
+CLASS="SECTION"
+><A
+NAME="AEN941"
+>4.3. Linking Scripts</A
+></H1
+><P
+>A linker script is used to instruct the linker about how to assemble the
+various sections into a completed binary. It consists of a series of
+directives which are considered in the order they are encountered.</P
+><P
+>The sections will appear in the resulting binary in the order they are
+specified in the script file. If a referenced section is not found, the linker will behave as though the
+section did exist but had a zero size, no relocations, and no exports.
+A section should only be referenced once. Any subsequent references will have
+an undefined effect.</P
+><P
+>All numbers are in linking scripts are specified in hexadecimal. All directives
+are case sensitive although the hexadecimal numbers are not.</P
+><P
+>A section name can be specified as a "*", then any section not
+already matched by the script will be matched. The "*" can be followed
+by a comma and a flag to narrow the section down slightly, also.
+If the flag is "!bss", then any section that is not flagged as a bss section
+will be matched. If the flag is "bss", then any section that is flagged as
+bss will be matched.</P
+><P
+>The following directives are understood in a linker script.</P
+><P
+></P
+><DIV
+CLASS="VARIABLELIST"
+><DL
+><DT
+>sectopt <CODE
+CLASS="PARAMETER"
+>section</CODE
+> padafter <CODE
+CLASS="PARAMETER"
+>byte,...</CODE
+></DT
+><DD
+><P
+>&#13;This will cause the linker to append the specified list of byte values
+(specified in hexadecimal separated by commas) to the end of the named
+section.  This is done once all instances of the specified section are
+collected together.  This has no effect if the specified section does not
+appear anywhere in any of the objects specified for linking. &#13;</P
+><P
+>&#13;If code depends on the presence of this padding somewhere, it is sufficient
+to include an empty section of the specified name in the object that depends
+on it.&#13;</P
+></DD
+><DT
+>define basesympat <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>&#13;This causes the linker to define a symbol for the ultimate base address of
+each section using the pattern specified by <CODE
+CLASS="PARAMETER"
+>string</CODE
+>. 
+In the string, %s can appear exactly once and will be replaced with the
+section name.  The base address is calculated after all instances of each
+section have been collapsed together.&#13;</P
+><P
+>&#13;It should be noted that if none of the objects to be linked contains a
+particular section name, there will be no base symbol defined for it, even
+if it is listed explicitly in the link script.  If code depends on the
+presence of these symbols, it is sufficient to include an empty section of
+the specified name in the object that depends on it.&#13;</P
+><P
+>  If the pattern resolves to the same string for multiple
+sections, the results are undefined.&#13;</P
+></DD
+><DT
+>define lensympat <CODE
+CLASS="PARAMETER"
+>string</CODE
+></DT
+><DD
+><P
+>&#13;This causes the linker to define a symbol for the ultimate length of each
+section using the pattern specified by <CODE
+CLASS="PARAMETER"
+>string</CODE
+>.  In
+the string, %s can appear exactly once and will be replaced with the section
+name.  The length is calculated after all instances of a section have been
+collapsed together.&#13;</P
+><P
+>&#13;It should be noted that if none of the objects to be linked contains a
+particular section name, there will be no length symbol defined for it, even
+if it is listed explicitly in the link script.  If code depends on the
+presence of these symbols, it is sufficient to include an empty section of
+the specified name in the object that depends on it.&#13;</P
+><P
+>If the pattern resolves to the same string for multiple
+sections, the results are undefined.&#13;</P
+></DD
+><DT
+>section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> load <CODE
+CLASS="PARAMETER"
+>addr</CODE
+></DT
+><DD
+><P
+>&#13;This causes the section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> to load at
+<CODE
+CLASS="PARAMETER"
+>addr</CODE
+>. For the raw target, only one "load at" entry is
+allowed for non-bss sections and it must be the first one. For raw targets,
+it affects the addresses the linker assigns to symbols but has no other
+affect on the output. bss sections may all have separate load addresses but
+since they will not appear in the binary anyway, this is okay.</P
+><P
+>For the decb target, each "load" entry will cause a new "block" to be
+output to the binary which will contain the load address. It is legal for
+sections to overlap in this manner - the linker assumes the loader will sort
+everything out.</P
+></DD
+><DT
+>section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> high <CODE
+CLASS="PARAMETER"
+>addr</CODE
+></DT
+><DD
+><P
+>&#13;This causes the section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> to load with its end
+address just below <CODE
+CLASS="PARAMETER"
+>addr</CODE
+>.  Subsequent sections are
+loaded at progressively lower addresses.  This may lead to inefficient file
+encoding for some targets.  As of this writing, it will also almost
+certainly do the wrong thing for a raw target.&#13;</P
+><P
+>&#13;This is useful for aligning a block of code with high memory.  As an
+example, if the total size of a section is $100 bytes and a high address of
+$FE00 is specified, the section will actually load at $FD00.&#13;</P
+></DD
+><DT
+>section <CODE
+CLASS="PARAMETER"
+>name</CODE
+></DT
+><DD
+><P
+>&#13;This will cause the section <CODE
+CLASS="PARAMETER"
+>name</CODE
+> to load after the previously listed
+section.</P
+></DD
+><DT
+>entry <CODE
+CLASS="PARAMETER"
+>addr or sym</CODE
+></DT
+><DD
+><P
+>This will cause the execution address (entry point) to be the address
+specified (in hex) or the specified symbol name. The symbol name must
+match a symbol that is exported by one of the object files being linked.
+This has no effect for targets that do not encode the entry point into the
+resulting file. If not specified, the entry point is assumed to be address 0
+which is probably not what you want. The default link scripts for targets
+that support this directive automatically starts at the beginning of the
+first section (usually "init" or "code") that is emitted in the binary.</P
+></DD
+><DT
+>pad <CODE
+CLASS="PARAMETER"
+>size</CODE
+></DT
+><DD
+><P
+>This will cause the output file to be padded with NUL bytes to be exactly
+<CODE
+CLASS="PARAMETER"
+>size</CODE
+> bytes in length. This only makes sense for a raw target.</P
+></DD
+></DL
+></DIV
+></DIV
+><DIV
+CLASS="NAVFOOTER"
+><HR
+ALIGN="LEFT"
+WIDTH="100%"><TABLE
+SUMMARY="Footer navigation table"
+WIDTH="100%"
+BORDER="0"
+CELLPADDING="0"
+CELLSPACING="0"
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+><A
+HREF="x927.html"
+ACCESSKEY="P"
+>Prev</A
+></TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="index.html"
+ACCESSKEY="H"
+>Home</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+><A
+HREF="x1007.html"
+ACCESSKEY="N"
+>Next</A
+></TD
+></TR
+><TR
+><TD
+WIDTH="33%"
+ALIGN="left"
+VALIGN="top"
+>Linker Operation</TD
+><TD
+WIDTH="34%"
+ALIGN="center"
+VALIGN="top"
+><A
+HREF="c827.html"
+ACCESSKEY="U"
+>Up</A
+></TD
+><TD
+WIDTH="33%"
+ALIGN="right"
+VALIGN="top"
+>Format Specific Linking Notes</TD
+></TR
+></TABLE
+></DIV
+></BODY
+></HTML
+>
\ No newline at end of file
--- a/extra/README	Mon Aug 05 21:07:14 2019 -0600
+++ b/extra/README	Mon Aug 05 21:27:09 2019 -0600
@@ -16,14 +16,17 @@
 
 Similar to the "as" script above except for lwar.
 
-gcc6809lw-4.6.1-1.patch
+gcc6809lw-*.patch
 
 These are patches to the main gcc source distribution for specific releases. 
-The last number after the dash is a patch level for the specific patch. 
-These are different to the official gcc6809 releases in the following ways. 
-First, all the source for as-6809 is removed.  Also, the special "helper"
-makefile and directory is removed. Also, as of this writing, the latest
-"official" release was for gcc 4.3.4 which does not build on 64 bit linux.
+The last number after the dash is a patch level for the specific patch. It
+is worth noting that a patch for a particular minor version of GCC may work
+with later minor versions in the same release sequence. That is, a patch
+for 4.6.1 might work with 4.6.4. These are different to the official
+gcc6809 releases in the following ways. First, all the source for as-6809
+is removed. Also, the special "helper" makefile and directory is removed. 
+Also, as of this writing, the latest "official" release was for gcc 4.3.4
+which does not build on 64 bit linux.
 
 In the event you have used the "official" gcc6809 with the default as6809
 assembler that comes with it, you should be aware that while lwasm is mostly
@@ -89,3 +92,19 @@
 for "root" set up correctly if your install prefix requires root privileges.
 
 The above is WOMM certified. YMMV.
+
+NOTES ABOUT SPECIFIC PATCHES
+============================
+
+Old gcc6809 patches have been removed to avoid confusion.
+
+The -6 patch fixes a code generation ICE. The previous -4 patch fixed a code
+generation error that could have a substantial impact. The -3 patch fixed
+some compatibilty with new lwtools versions. The -2 patch fixed a major set
+of ICEs by completely removing the "soft registers" business. They're
+apparently not needed with gcc 4.6.x at all and it's not clear they were
+even needed with gcc 4.3.x. They also had the side effect of causing things
+to break even if they weren't in use so they had to go. In other words, the
+-6 patch is the current best version to use so there's no point including
+the old ones.
+
--- a/extra/ar	Mon Aug 05 21:07:14 2019 -0600
+++ b/extra/ar	Mon Aug 05 21:27:09 2019 -0600
@@ -61,4 +61,6 @@
 fi
 
 # Run the real lwar with translated options.
-exec lwar $options $*
+# --nopaths is given to get the proper standard "ar" behaviour
+# which doesn't store path names
+exec lwar --nopaths $options $*
--- a/extra/as	Mon Aug 05 21:07:14 2019 -0600
+++ b/extra/as	Mon Aug 05 21:27:09 2019 -0600
@@ -40,7 +40,6 @@
 output_file=
 list_file=
 options=
-list_file_enabled=n
 
 # Parse the command-line options.  See the GNU 'as' man page for
 # an explanation of all these options.  Our goal is to translate
@@ -70,10 +69,11 @@
 		--)
 			fatal_error "standard input not supported"
 			;;
-#		-a*)
-#			options="${options}lc"
-#			list_file_enabled=y
-#			;;
+		-a*)
+			list_file=${arg#${arg%=*}}
+			list_file=${list_file#=}
+			options="$options -l$list_file"
+			;;
 		-I*)
 			#include_file=${arg#-I}
 			#echo "warning: include path '$include_file' ignored"
@@ -84,6 +84,9 @@
 		-o)
 			output_file=$1; shift
 			;;
+		--defsym)
+			options="${options} -D$1"; shift
+			;;
 		-v|-version)
 			show_version
 			;;
@@ -95,10 +98,6 @@
 			# These options are accepted but ignored by GNU as.
 			true
 			;;
-#		=*)
-#			# Set the name of the listing file
-#			list_file=${arg#=}
-#			;;
 		-Qy)
 			# "identify in output" - ignore
 			true
@@ -126,7 +125,9 @@
 # --pragma=undefextern causes undefined symbols to be assumed external
 # --pragma=cescapes allows C escape syntax in strings
 #echo lwasm -o "$output_file" $options --obj --pragma=undefextern --pragma=cescapes $input_file
-lwasm -o "$output_file" $options --obj --pragma=undefextern --pragma=cescapes --pragma=importundefexport $input_file
+# pragma=newsource allows preprocessed asm files with macro expansion to assemble properly even
+# when the preprocessor interproses extra spaces
+lwasm -o "$output_file" $options --obj --pragma=undefextern --pragma=cescapes --pragma=importundefexport --pragma=newsource $input_file
 rc=$?
 
 # OK, see if the assembler succeeded or not.
@@ -140,7 +141,7 @@
 
 if [ "$rc" != "0" ]; then
 	cp -p $input_file /tmp/as6809_error.s
-	rm -f $asoutput_file
+	rm -f $output_file $list_file
 	exit $rc
 fi
 
--- a/extra/gcc6809lw-4.6.1-1.patch	Mon Aug 05 21:07:14 2019 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8160 +0,0 @@
-diff -urN gcc-4.6.1-orig/config.sub gcc-4.6.1/config.sub
---- gcc-4.6.1-orig/config.sub	2010-05-25 07:22:07.000000000 -0600
-+++ gcc-4.6.1/config.sub	2011-09-17 14:07:51.597643628 -0600
-@@ -313,7 +313,7 @@
- 	c6x)
- 		basic_machine=tic6x-unknown
- 		;;
--	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
-+	m6809 | m6811 | m68hc11 | m6812 | m68hc12 | picochip)
- 		# Motorola 68HC11/12.
- 		basic_machine=$basic_machine-unknown
- 		os=-none
-@@ -354,7 +354,7 @@
- 	| i*86-* | i860-* | i960-* | ia64-* \
- 	| ip2k-* | iq2000-* \
- 	| lm32-* \
--	| m32c-* | m32r-* | m32rle-* \
-+	| m32c-* | m32r-* | m32rle-* | m6809-* \
- 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- 	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
- 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-@@ -509,6 +509,10 @@
- 		basic_machine=arm-unknown
- 		os=-cegcc
- 		;;
-+	coco)
-+		basic_machine=coco
-+		os=-none
-+		;;
- 	convex-c1)
- 		basic_machine=c1-convex
- 		os=-bsd
-diff -urN gcc-4.6.1-orig/configure gcc-4.6.1/configure
---- gcc-4.6.1-orig/configure	2011-03-16 12:27:36.000000000 -0600
-+++ gcc-4.6.1/configure	2011-09-17 14:06:01.187643616 -0600
-@@ -3441,6 +3441,9 @@
-   m32r-*-*)
-     noconfigdirs="$noconfigdirs ${libgcj}"
-     ;;
-+  m6809*)
-+    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
-+    ;;
-   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
-     noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
-     libgloss_dir=m68hc11
-diff -urN gcc-4.6.1-orig/configure.ac gcc-4.6.1/configure.ac
---- gcc-4.6.1-orig/configure.ac	2011-03-16 12:27:36.000000000 -0600
-+++ gcc-4.6.1/configure.ac	2011-09-17 14:06:01.187643616 -0600
-@@ -887,6 +887,9 @@
-   m32r-*-*)
-     noconfigdirs="$noconfigdirs ${libgcj}"
-     ;;
-+  m6809*)
-+    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
-+    ;;
-   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
-     noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
-     libgloss_dir=m68hc11
-diff -urN gcc-4.6.1-orig/gcc/calls.c gcc-4.6.1/gcc/calls.c
---- gcc-4.6.1-orig/gcc/calls.c	2011-06-06 05:46:14.000000000 -0600
-+++ gcc-4.6.1/gcc/calls.c	2011-09-17 14:06:01.217643616 -0600
-@@ -2434,7 +2434,7 @@
- 	 call sequence.
- 	 Also do the adjustments before a throwing call, otherwise
- 	 exception handling can fail; PR 19225. */
--      if (pending_stack_adjust >= 32
-+      if (pending_stack_adjust >= 8
- 	  || (pending_stack_adjust > 0
- 	      && (flags & ECF_MAY_BE_ALLOCA))
- 	  || (pending_stack_adjust > 0
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/crt0.S gcc-4.6.1/gcc/config/m6809/crt0.S
---- gcc-4.6.1-orig/gcc/config/m6809/crt0.S	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/crt0.S	2011-09-17 14:06:01.227643616 -0600
-@@ -0,0 +1,180 @@
-+;;;
-+;;; Copyright 2006, 2007, 2008, 2009 by Brian Dominy <brian@oddchange.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/>.
-+
-+	/* Declare external for main() */
-+	.globl _main
-+
-+
-+/* The startup is heavily dependent on the type of machine and
-+OS environment that is available at the start point.
-+For the most part, the general idea is the same across machines,
-+but the implementation is vastly different.  This is managed via
-+conditional compiles throughout the startup code for each of the
-+supported machines. */
-+
-+#ifdef TARGET_COCO /* CoCo memory map */
-+
-+#define COCO_RAMROM_MODE 0xFFDE
-+#define COCO_ALLRAM_MODE 0xFFDF
-+#define COCO_PAGE1 0xFFD5
-+
-+/* SAM M1 and M0 adjusts the memory size */
-+
-+#define BASIC_WARMSTART_FLAG 0x0071
-+#define BASIC_START 0xA027
-+
-+#define __STACK_TOP 0x6800
-+
-+#else /* Simulator (default) memory map */
-+
-+#define SIM_EXIT_REG 0xFF01
-+
-+#define __STACK_TOP 0xFE00
-+
-+#endif
-+
-+
-+	/* Declare all linker sections, and combine them into a single bank */
-+	.bank	prog
-+	.area	.text  (BANK=prog)
-+	.area .data  (BANK=prog)
-+	.area .ctors (BANK=prog)
-+	.word 0
-+	.area .dtors (BANK=prog)
-+	.word 0
-+	.area .bss   (BANK=prog)
-+
-+   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	;;;
-+	;;; __exit : Exit point from the program
-+	;;; For simulation, this writes to a special I/O register that
-+	;;; the simulator interprets as end-of-program.
-+	;;;
-+   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area	.text
-+ 	.globl __exit
-+__exit:
-+#ifdef TARGET_COCO
-+	;; Go back to ROM/RAM mode
-+	sta	COCO_RAMROM_MODE
-+	clr	BASIC_WARMSTART_FLAG
-+	jmp   BASIC_START
-+#else
-+	tfr	x,d
-+	stb	SIM_EXIT_REG
-+	bra	__exit
-+#endif
-+
-+
-+   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	;;;
-+	;;; __start : Entry point to the program
-+	;;;
-+   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area	.text
-+	.globl __start
-+__start:
-+
-+#ifdef HAVE_DIRECT
-+	;; Initialize the direct page pointer
-+	lda	#<s_.direct
-+	tfr	a,dp
-+#endif
-+
-+#ifdef TARGET_COCO
-+	;; Turn off interrupts
-+	orcc #(0x10|0x40)
-+	
-+	;; Setup All RAM Mode
-+	sta COCO_ALLRAM_MODE
-+#endif /* TARGET_COCO */
-+
-+	;; Initialize the stack
-+	lds	#__STACK_TOP - 2
-+	
-+	;; Call any "initializer" functions
-+	ldu	#s_.ctors
-+__ctors_loop:
-+	ldy	,u++
-+	cmpy	#0
-+	beq	__ctors_done
-+	jsr	,y
-+	bra	__ctors_loop
-+__ctors_done:
-+
-+	;; Enable interrupts on the simulator
-+#ifndef TARGET_COCO
-+	andcc	#~(0x10|0x40)
-+#endif
-+
-+	;; Set up the environment
-+
-+	;; Set up argc/argv arrays
-+
-+	;; Call the main function.  The exit code will
-+	;; be returned in the X register, unless compiled
-+	;; with -mdret, in which case it comes back in D.
-+	jsr	_main
-+
-+	;; Call any finalizer functions
-+	ldu	#s_.dtors
-+__dtors_loop:
-+	ldy	,u++
-+	cmpy	#0
-+	beq	__dtors_done
-+	jsr	,y
-+	bra	__dtors_loop
-+__dtors_done:
-+
-+	;; If main returns, then invoke _exit() to stop the program
-+	;; The C library doesn't support -mdret yet, so move the
-+	;; argument first.
-+#ifdef __DRET__
-+	tfr	d,x
-+#endif
-+	jmp	_exit
-+
-+
-+
-+	;;;
-+	;;; __crt0_vector : Default handler for interrupts
-+	;;;
-+	.area	.text
-+___crt0_vector:
-+	;; The default behavior is to simply ignore all
-+	;; non-reset interrupts.
-+	rti
-+
-+
-+	;;;
-+	;;; vector : The interrupt vector table
-+	;;; The linker will ensure that this gets loaded at address 0xFFF0.
-+	;;;
-+	.area vector
-+vectors:
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word ___crt0_vector
-+	.word __start
-+
-+	.end __start
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/libgcc1.s gcc-4.6.1/gcc/config/m6809/libgcc1.s
---- gcc-4.6.1-orig/gcc/config/m6809/libgcc1.s	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/libgcc1.s	2011-09-17 14:06:01.227643616 -0600
-@@ -0,0 +1,511 @@
-+/* libgcc routines for m6809
-+   Copyright (C) 2006 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 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/>.  */
-+
-+/* As a special exception, if you link this library with other files,
-+   some of which are compiled with GCC, to produce an executable,
-+   this library does not by itself cause the resulting executable
-+   to be covered by the GNU General Public License.
-+   This exception does not however invalidate any other reasons why
-+   the executable file might be covered by the GNU General Public License.  */
-+
-+
-+#define SIGFPE jmp _abort
-+
-+
-+	; Shift functions
-+	; On input, D is value to be shifted, and X has shift count.
-+	; Result is also in D.
-+
-+#ifdef L_ashlhi3
-+	.area .text
-+	.globl _ashlhi3
-+_ashlhi3:
-+	pshs	x
-+1$:
-+	leax	-1,x
-+	cmpx	#-1
-+	beq	2$
-+	aslb
-+	rola
-+	bra	1$
-+2$:
-+	puls	x,pc
-+#endif
-+
-+#ifdef L_ashrhi3
-+	.area .text
-+	.globl _ashrhi3
-+_ashrhi3:
-+	pshs	x
-+1$:
-+	leax	-1,x
-+	cmpx	#-1
-+	beq	2$
-+	asra
-+	rorb
-+	bra	1$
-+2$:
-+	puls	x,pc
-+#endif
-+
-+
-+#ifdef L_lshrhi3
-+	.area .text
-+	.globl _lshrhi3
-+_lshrhi3:
-+	pshs	x
-+1$:
-+	leax	-1,x
-+	cmpx	#-1
-+	beq	2$
-+	lsra
-+	rorb
-+	bra	1$
-+2$:
-+	puls	x,pc
-+#endif
-+
-+
-+
-+#ifdef L_softregs
-+	.area		direct
-+	.globl	m0, m1, m2, m3, m4, m5, m6, m7
-+	.globl	m8, m9, m10, m11, m12, m13, m14, m15
-+m0: .blkb 1
-+m1: .blkb 1
-+m2: .blkb 1
-+m3: .blkb 1
-+m4: .blkb 1
-+m5: .blkb 1
-+m6: .blkb 1
-+m7: .blkb 1
-+m8: .blkb 1
-+m9: .blkb 1
-+m10: .blkb 1
-+m11: .blkb 1
-+m12: .blkb 1
-+m13: .blkb 1
-+m14: .blkb 1
-+m15: .blkb 1
-+#endif
-+
-+
-+#ifdef L_ashlsi3_one
-+	.area		.text
-+	.globl	_ashlsi3_one
-+_ashlsi3_one:
-+	asl	3,x
-+	rol	2,x
-+	rol	1,x
-+	rol	,x
-+	rts
-+#endif
-+
-+#ifdef L_ashlsi3
-+	/* X points to the SImode (source/dest)
-+		B is the count */
-+_ashlsi3:
-+	pshs	u
-+	cmpb	#16
-+	blt	try8
-+	subb	#16
-+	; Shift by 16
-+	ldu	2,x
-+	stu	,x
-+try8:
-+	cmpb	#8
-+	blt	try_rest
-+	subb	#8
-+	; Shift by 8
-+
-+try_rest:
-+	tstb
-+	beq	done
-+do_rest:
-+	; Shift by 1
-+	asl	3,x
-+	rol	2,x
-+	rol	1,x
-+	rol	,x
-+	decb
-+	bne	do_rest
-+done:
-+	puls	u,pc
-+#endif
-+
-+#ifdef L_ashrsi3_one
-+	.area		.text
-+	.globl	_ashlsi3_one
-+_ashrsi3_one:
-+	asr	,x
-+	ror	1,x
-+	ror	2,x
-+	ror	3,x
-+	rts
-+#endif
-+
-+
-+#ifdef L_lshrsi3_one
-+	.area		.text
-+	.globl	_lshrsi3_one
-+_lshrsi3_one:
-+	lsr	,x
-+	ror	1,x
-+	ror	2,x
-+	ror	3,x
-+	rts
-+#endif
-+
-+
-+#ifdef L_clzsi2
-+	.area .text
-+	.globl ___clzhi2
-+	; Input: X = 16-bit unsigned integer
-+	; Output: X = number of leading zeros
-+	; This function destroys the value in D.
-+___clzhi2:
-+	pshs	x
-+	; Find the offset of the leftmost '1' bit in
-+	; the left half of the word.
-+	;
-+	; Bits are numbered in the table with 1 meaning the
-+	; LSB and 8 meaning the MSB.
-+	;
-+	; If nonzero, then clz is 8-a.
-+	tfr	x,d
-+	ldx	#___clz_tab
-+	tfr	a,b
-+	clra
-+	ldb	d,x
-+	bne	upper_bit_set
-+
-+lower_bit_set:
-+	; If the upper byte is zero, then check the lower
-+	; half of the word.  Return 16-a.
-+	puls	d
-+	clra
-+	ldb	d,x
-+	negb
-+	addb	#16
-+	bra	done
-+
-+upper_bit_set:
-+	negb
-+	addb	#8
-+	puls	x
-+
-+done:
-+	tfr	d,x
-+	puls	pc
-+#endif
-+
-+#ifdef L_clzdi2
-+	.area .text
-+	.globl ___clzsi2
-+	; Input: 32-bit unsigned integer is on the stack, just
-+	; above the return address
-+	; Output: X = number of leading zeros
-+___clzsi2:
-+	; Check the upper 16-bit word
-+	; If it is not zero, then return clzhi2(X).
-+	; A branch can be used instead of a call since no
-+	; postprocessing is needed.  Use long branch form
-+	; though since functions may not be near each other.
-+	ldx	2,s
-+	lbne	___clzhi2
-+	ldx	4,s
-+	jsr	___clzhi2
-+	leax	16,x
-+	rts
-+#endif
-+
-+#ifdef L_ctzsi2
-+	.area .text
-+	.globl ___ctzhi2
-+	; Input: X = 16-bit unsigned integer
-+	; Output: X = number of trailing zeros
-+	; F(x) = 15 - clzhi2(X & -x)
-+	; This function destroys the value in D.
-+___ctzhi2:
-+	tfr	x,d
-+	coma
-+	comb
-+	addd	#1
-+	pshs	a
-+	pshs	b
-+	tfr	x,d
-+	andb	,s+
-+	anda	,s+
-+	tfr	d,x
-+	jsr	___clzhi2
-+	tfr	x,d
-+	subd	#16
-+	coma
-+	comb
-+	tfr	d,x
-+	rts
-+#endif
-+
-+
-+#ifdef L_ctzdi2
-+	.area .text
-+	.globl ___ctzsi2
-+	; Input: 32-bit unsigned integer is on the stack, just
-+	; above the return address
-+	; Output: X = number of leading zeros
-+___ctzsi2:
-+	; Check the lower 16-bit word
-+	; If it is not zero, then return ctzhi2(X).
-+	; A branch can be used instead of a call since no
-+	; postprocessing is needed.  Use long branch form
-+	; though since functions may not be near each other.
-+	ldx	4,s
-+	lbne	___ctzhi2
-+	ldx	2,s
-+	jsr	___ctzhi2
-+	leax	16,x
-+	rts
-+#endif
-+
-+
-+#ifdef L_mulhi3
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;;; ___mulhi3 - signed/unsigned multiply
-+;;; Called by GCC to implement 16x16 multiplication
-+;;; Arguments: Two 16-bit values, one in stack, one in X.
-+;;; Result: 16-bit result in X
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area .text
-+	.globl _mulhi3
-+_mulhi3:
-+	pshs	x
-+	lda   5,s   ; left msb * right lsb * 256
-+	ldb   ,s
-+	mul
-+	tfr   b,a
-+	clrb
-+	tfr   d,x
-+	ldb   1,s   ; left lsb * right msb * 256
-+	lda   4,s
-+	mul
-+	tfr   b,a
-+	clrb
-+	leax  d,x
-+	ldb   1,s   ; left lsb * right lsb
-+	lda   5,s
-+	mul
-+	leax  d,x
-+	puls	d,pc  ; kill D to remove initial push
-+#endif
-+
-+
-+#ifdef L_divhi3
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;;; ___divhi3 - signed division
-+;;; Arguments: Dividend in X, divisor on the stack
-+;;; Returns result in X.
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area .text
-+	.globl _divhi3
-+_divhi3:
-+	ldd	2,s
-+	bne	do_div		; check dividend
-+	SIGFPE
-+do_div:
-+	pshs	x
-+	jsr	_seuclid
-+	puls	x,pc
-+#endif
-+
-+
-+#ifdef L_modhi3
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;;; ___modhi3 - signed modulo
-+;;; Arguments: Dividend in X, divisor on the stack
-+;;; Returns result in X.
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area .text
-+	.globl _modhi3
-+_modhi3:
-+	ldd	2,s
-+	bne	do_mod		; check dividend
-+	SIGFPE
-+do_mod:
-+	pshs	x
-+	jsr	_seuclid
-+	leas	2,s
-+	tfr	d,x
-+	rts
-+#endif
-+
-+
-+
-+#ifdef L_udivhi3
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;;; ___udivhi3 - unsigned division
-+;;; Arguments: Dividend in X, divisor on the stack
-+;;; Returns result in X.
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area .text
-+	.globl _udivhi3
-+_udivhi3:
-+	ldd	2,s
-+	bne	do_udiv		; check dividend
-+	SIGFPE
-+do_udiv:
-+	pshs	x
-+	jsr	_euclid
-+	puls	x,pc
-+#endif
-+
-+
-+#ifdef L_umodhi3
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+;;; ___umodhi3 - unsigned modulo
-+;;; Arguments: Dividend in X, divisor on the stack
-+;;; Returns result in X.
-+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-+	.area .text
-+	.globl _umodhi3
-+_umodhi3:
-+	ldd	2,s
-+	bne	do_umod		; check dividend
-+	SIGFPE
-+do_umod:
-+	pshs	x
-+	jsr	_euclid
-+	leas	2,s
-+	tfr	d,x
-+	rts
-+#endif
-+
-+
-+#ifdef L_euclid
-+;	unsigned euclidean division
-+;	calling: (left / right)
-+;		push left
-+;		ldd right
-+;		jsr _euclid
-+;	quotient on the stack (left)
-+;	modulus in d
-+
-+	.area	.text
-+	.globl	_euclid
-+	left=5
-+	right=1			; word
-+	count=0			; byte
-+	CARRY=1			; alias
-+_euclid:
-+	leas	-3,s		; 2 local variables
-+	clr	count,s		; prescale divisor
-+	inc	count,s
-+	tsta
-+presc:
-+	bmi	presc_done
-+	inc	count,s
-+	aslb
-+	rola
-+	bra	presc
-+presc_done:
-+	std	right,s
-+	ldd	left,s
-+	clr	left,s		; quotient = 0
-+	clr	left+1,s
-+mod1:
-+	subd	right,s		; check subtract
-+	bcc	mod2
-+	addd	right,s
-+	andcc	#~CARRY
-+	bra	mod3
-+mod2:
-+	orcc	#CARRY
-+mod3:
-+	rol	left+1,s	; roll in carry
-+	rol	left,s
-+	lsr	right,s
-+	ror	right+1,s
-+	dec	count,s
-+	bne	mod1
-+	leas	3,s
-+	rts
-+#endif
-+
-+#ifdef L_seuclid
-+;	signed euclidean division
-+;	calling: (left / right)
-+;		push left
-+;		ldd right
-+;		jsr _seuclid
-+;	quotient on the stack (left)
-+;	modulus in d
-+	.area	.text
-+	.globl	_seuclid
-+	left=6
-+	right=2
-+	quot_sign=1
-+	mod_sign=0
-+_seuclid:
-+	leas	-4,s		; 3 local variables
-+	std	right,s
-+	clr	mod_sign,s
-+	clr	quot_sign,s
-+	ldd	left,s
-+	bge	mod_abs
-+	inc	mod_sign,s	; sign(mod) = sign(left)
-+	inc	quot_sign,s
-+	bsr	negd		; abs(left) -> D
-+mod_abs:
-+	pshs	b,a		; push abs(left)
-+	ldd	right+2,s	; all references shifted by 2
-+	bge	quot_abs
-+	dec	quot_sign+2,s	; sign(quot) = sign(left) XOR sign(right)
-+	bsr	negd		; abs(right) -> D
-+quot_abs:
-+	jsr	_euclid		; call (unsigned) euclidean division
-+	std	right+2,s
-+	puls	a,b		; quot -> D
-+	tst	quot_sign,s	; all references no longer shifted
-+	beq	quot_done
-+	bsr	negd
-+quot_done:
-+	std	left,s		; quot -> left
-+	ldd	right,s
-+	tst	mod_sign,s
-+	beq	mod_done
-+	bsr	negd
-+mod_done:
-+	leas	4,s		; destroy stack frame
-+	rts
-+
-+negd:				; self-explanatory !
-+	nega
-+	negb
-+	sbca	#0
-+	rts
-+#endif
-+
-+
-+
-+#ifdef L_pending_addsi3
-+_addsi3:
-+	rts
-+#endif /* L_pending_addsi3 */
-+
-+
-+
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/m6809.c gcc-4.6.1/gcc/config/m6809/m6809.c
---- gcc-4.6.1-orig/gcc/config/m6809/m6809.c	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/m6809.c	2011-09-18 19:48:42.137654855 -0600
-@@ -0,0 +1,3013 @@
-+/*-------------------------------------------------------------------
-+	FILE: m6809.c
-+-------------------------------------------------------------------*/
-+/* Subroutines for insn-output.c for MC6809.
-+   Copyright (C) 1989-2007 Free Software Foundation, Inc.
-+
-+ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
-+ Space Astronomy Laboratory
-+ University of Wisconsin at Madison
-+
-+ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
-+ ( msdoerfe@informatik.uni-erlangen.de )
-+ also added #pragma interrupt (inspired by gcc-6811)
-+
-+ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
-+ (ebotcazou@multimania.com)
-+
-+ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
-+ (ebotcazou@multimania.com)
-+
-+ major cleanup, improvements, and upgrade to gcc 3.4 by Brian Dominy
-+ (brian@oddchange.com)
-+
-+ additional adjustments, etc., for gcc 4.6.1 by William Astle (lost@l-w.ca)
-+
-+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/>.  */
-+
-+#include <string.h>
-+#include <time.h>
-+#include <sys/types.h>
-+#include <sys/timeb.h>
-+#include <stdio.h>
-+#include "config.h"
-+#include "system.h"
-+#include "coretypes.h"
-+#include "tm.h"
-+#include "tree.h"
-+#include "rtl.h"
-+#include "tm_p.h"
-+#include "regs.h"
-+#include "flags.h"
-+#include "hard-reg-set.h"
-+#include "real.h"
-+#include "tree.h"
-+#include "insn-config.h"
-+#include "conditions.h"
-+#include "insn-flags.h"
-+#include "output.h"
-+#include "insn-attr.h"
-+#include "function.h"
-+#include "target.h"
-+#include "target-def.h"
-+#include "expr.h"
-+#include "recog.h"
-+#include "cpplib.h"
-+#include "c-family/c-pragma.h"
-+#include "c-family/c-common.h"
-+#include "toplev.h"
-+#include "optabs.h"
-+#include "version.h"
-+#include "df.h"
-+#include "rtlhooks-def.h"
-+
-+/* macro to return TRUE if length of operand mode is one byte */
-+#define BYTE_MODE(X) ((GET_MODE_SIZE (GET_MODE (X))) == 1)
-+
-+
-+/* REAL_REG_P(x) is a true if the rtx 'x' represents a real CPU
-+register and not a fake one that is emulated in software. */
-+#define REAL_REG_P(x) (REG_P(x) && !M_REG_P(x))
-+
-+/*-------------------------------------------------------------------
-+    Target hooks, moved from target.h
-+-------------------------------------------------------------------*/
-+static void m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED);
-+
-+#undef TARGET_ENCODE_SECTION_INFO
-+#define TARGET_ENCODE_SECTION_INFO m6809_encode_section_info
-+
-+#undef TARGET_ASM_FILE_START
-+#define TARGET_ASM_FILE_START m6809_asm_file_start
-+
-+#undef TARGET_ASM_ALIGNED_HI_OP
-+#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
-+
-+#undef TARGET_ASM_ALIGNED_SI_OP
-+#define TARGET_ASM_ALIGNED_SI_OP NULL
-+
-+#undef TARGET_ASM_UNALIGNED_HI_OP
-+#define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
-+
-+#undef TARGET_ASM_UNALIGNED_SI_OP
-+#define TARGET_ASM_UNALIGNED_SI_OP NULL
-+
-+#undef TARGET_RTX_COSTS
-+#define TARGET_RTX_COSTS m6809_rtx_costs
-+
-+#undef TARGET_ATTRIBUTE_TABLE
-+#define TARGET_ATTRIBUTE_TABLE m6809_attribute_table
-+
-+#undef TARGET_INIT_BUILTINS
-+#define TARGET_INIT_BUILTINS m6809_init_builtins
-+
-+#undef TARGET_EXPAND_BUILTIN
-+#define TARGET_EXPAND_BUILTIN m6809_expand_builtin
-+
-+#undef TARGET_DEFAULT_TARGET_FLAGS
-+#define TARGET_DEFAULT_TARGET_FLAGS (MASK_REG_ARGS | MASK_DIRECT)
-+
-+#undef TARGET_FUNCTION_OK_FOR_SIBCALL
-+#define TARGET_FUNCTION_OK_FOR_SIBCALL m6809_function_ok_for_sibcall
-+
-+#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
-+#define TARGET_ASM_TRAMPOLINE_TEMPLATE m6809_asm_trampoline_template
-+
-+#undef TARGET_TRAMPOLINE_INIT
-+#define TARGET_TRAMPOLINE_INIT m6809_initialize_trampoline
-+
-+#undef TARGET_FRAME_POINTER_REQUIRED
-+#define TARGET_FRAME_POINTER_REQUIRED m6809_frame_pointer_required
-+
-+#undef TARGET_OPTION_OVERRIDE
-+#define TARGET_OPTION_OVERRIDE m6809_override_options
-+
-+/* External variables used */
-+extern int reload_completed;   /* set in toplev.c */
-+extern FILE *asm_out_file;
-+
-+static int last_mem_size;   /* operand size (bytes) */
-+
-+/* True if the section was recently changed and another .area
-+ * directive needs to be output before emitting the next label. */
-+int section_changed = 0;
-+
-+/* Section names.  The defaults here are used until an
-+ * __attribute__((section)) is seen that changes it. */
-+char code_section_op[128] = "\t.area .text";
-+char data_section_op[128] = "\t.area .data";
-+char bss_section_op[128] = "\t.area .bss";
-+const char *code_bank_option = 0;
-+
-+/* TRUE if the direct mode prefix might be valid in this context.
-+ * This is set by 'print_address' prior to calling output_addr_const,
-+ * which performs into 'print_direct_prefix' to do the final checks. */
-+static int check_direct_prefix_flag;
-+
-+/* Nonzero if an address is being printed in a context which does not
-+ * permit any PIC modifications to the address */
-+static int pic_ok_for_addr_p = 1;
-+
-+/* Current code page.  This supports machines which can do bank
-+ * switching to allow for more than 64KB of code/data. */
-+char far_code_page[64];
-+
-+/* Current bank name */
-+static char current_bank_name[8] = "-1";
-+
-+/* Default bank name */
-+static char default_code_bank_name[8] = "-1";
-+
-+/* Direct memory reserved as soft registers */
-+unsigned int m6809_soft_regs = 0;
-+
-+/* ABI version */
-+unsigned int m6809_abi_version = M6809_ABI_VERSION_REGS;
-+
-+
-+/**
-+ * Called after options have been parsed.
-+ * If overrides have been specified on the command-line, then
-+ * these values are copied into the main storage variables.
-+ */
-+void
-+m6809_override_options (void)
-+{
-+	/* Handle -mfar-code-page */
-+	if (far_code_page_option == 0)
-+		far_code_page_option = "__default_code_page";
-+	strcpy (far_code_page, far_code_page_option);
-+
-+	/* Handle -mcode-section, -mdata-section, and -mbss-section */
-+	if (code_section_ptr != 0)
-+		sprintf (code_section_op, "\t.area %s", code_section_ptr);
-+	if (data_section_ptr != 0)
-+		sprintf (data_section_op, "\t.area %s", data_section_ptr);
-+	if (bss_section_ptr != 0)
-+		sprintf (bss_section_op, "\t.area %s", bss_section_ptr);
-+
-+	/* Handle -mcode-bank */
-+	if (code_bank_option != 0)
-+		sprintf (default_code_bank_name, "%s", code_bank_option);
-+
-+	/* Handle -mabi-version or -mno-reg-args */
-+	if (m6809_abi_version_ptr != 0)
-+	{
-+		if (!strcmp (m6809_abi_version_ptr, "stack"))
-+			m6809_abi_version = M6809_ABI_VERSION_STACK;
-+		else if (!strcmp (m6809_abi_version_ptr, "regs"))
-+			m6809_abi_version = M6809_ABI_VERSION_REGS;
-+		else if (!strcmp (m6809_abi_version_ptr, "bx"))
-+			m6809_abi_version = M6809_ABI_VERSION_BX;
-+		else if (!strcmp (m6809_abi_version_ptr, "latest"))
-+			m6809_abi_version = M6809_ABI_VERSION_LATEST;
-+		else
-+			m6809_abi_version = atoi (m6809_abi_version_ptr);
-+	}
-+
-+	/* The older -mno-reg-args option is deprecated, and treated
-+	as -mabi=stack. */
-+	if (!TARGET_REG_ARGS)
-+   {
-+      warning (WARNING_OPT "-mno-reg-args deprecated; use -mabi=stack instead.");
-+      m6809_abi_version = M6809_ABI_VERSION_STACK;
-+   }
-+
-+	/* -fexceptions is unsupported */
-+	flag_exceptions = 0;
-+	flag_non_call_exceptions = 0;
-+	flag_unwind_tables = 0;
-+}
-+
-+
-+/**
-+ * Output prefix that directs the assembler to use a direct-mode
-+ * instruction if globally enabled, address is a symbol, and symbol
-+ * has been marked as in direct page.  Also, never do this if
-+ * using the indirect mode. */
-+void
-+print_direct_prefix (FILE * file, rtx addr)
-+{
-+	if (TARGET_DIRECT &&
-+       (GET_CODE (addr) == SYMBOL_REF) && 
-+       SYMBOL_REF_FLAG (addr) &&
-+       check_direct_prefix_flag)
-+   {
-+      putc ('*', file);
-+   }
-+}
-+
-+
-+/** Prints an operand (that is not an address) in assembly from RTL. */
-+void
-+print_operand (FILE * file, rtx x, int code)
-+{
-+	if (REG_P (x)) {
-+		/* gcc currently allocates the entire 16-bit 'd' register
-+		 * even when it only needs an 8-bit value.  So here it
-+		 * is tricked into printing only the lower 8-bit 'b'
-+		 * register into the assembly output.
-+		 *
-+		 * Eventually gcc should be modified to allocate a/b
-+		 * independently and this hack can be removed.
-+		 *
-+		 * Occasionally, we may want to do an operation using
-+		 * the 'a' register instead of 'b'; use the 'A' code
-+		 * to specify that.
-+		 */
-+		if (code == 'A')
-+			fputs ("a", file);
-+		else if ((BYTE_MODE (x)) && (REGNO (x) == HARD_D_REGNUM))
-+			fputs ("b", file);
-+		else if (M_REG_P (x) && code == 'L')
-+			/* Soft registers can be treated like memory and accessed
-+			 * at a particular offset. TODO : handle 'W' */
-+			fputs (reg_names[REGNO (x)+1], file);
-+		else
-+			fputs (reg_names[REGNO (x)], file);
-+	}
-+
-+	else if (MEM_P (x)) {
-+		last_mem_size = GET_MODE_SIZE (GET_MODE (x));
-+		if (code == 'L') {	/* LSH of word address */
-+			if (GET_CODE (XEXP (x, 0)) == MEM)
-+			{
-+				/* Offseting an indirect addressing mode is not supported */
-+				error ("expression too complex for 6809 (offset indirect mode)");
-+				debug_rtx (x);
-+			}
-+			else
-+				x = adjust_address (x, QImode, 1);
-+		}
-+		else if (code == 'M') { /* MSH of word address */
-+			if (GET_CODE (XEXP (x, 0)) == MEM)
-+			{
-+				/* Offseting an indirect addressing mode is not supported */
-+				error ("expression too complex for 6809 (offset indirect mode)");
-+				debug_rtx (x);
-+			}
-+			else
-+				x = adjust_address (x, QImode, 0);
-+		}
-+		else if (code == 'W') { /* least significant half of 32-bit */
-+			x = adjust_address (x, HImode, 2);
-+		}
-+
-+		pic_ok_for_addr_p = (code != 'C');
-+		output_address (XEXP (x, 0));
-+	}
-+
-+	else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) {
-+		union { double d; int i[2]; } u;
-+		u.i[0] = CONST_DOUBLE_LOW (x);
-+		u.i[1] = CONST_DOUBLE_HIGH (x);
-+		fprintf (file, "#%#9.9g", u.d);
-+	}
-+
-+	else if (code == 'R') {
-+		fprintf (file, "%s", 
-+			m6809_get_regs_printable (INTVAL (x)));
-+	}
-+
-+	else {
-+		if (code == 'L') {	/* LSH of word address */
-+			x = gen_rtx_CONST_INT (VOIDmode, (INTVAL(x) & 0xff));
-+		}
-+		else if (code == 'M') {	/* MSH of word address */
-+			x = gen_rtx_CONST_INT (VOIDmode, ((INTVAL(x) >> 8) & 0xff));
-+		}
-+
-+		putc ('#', file);
-+		output_addr_const (file, x);
-+	}
-+}
-+
-+
-+/** Prints an address operand to assembler from its RTL representation. */
-+void
-+print_operand_address (FILE *file, rtx addr)
-+{
-+	register rtx base = 0;
-+	register rtx offset = 0;
-+	int regno;
-+	int indirect_flag = 0;
-+
-+	check_direct_prefix_flag = 0;
-+
-+	/*** check for indirect addressing ***/
-+	if (MEM_P (addr)) {
-+		last_mem_size = GET_MODE_SIZE (GET_MODE (addr));
-+		addr = XEXP (addr, 0);
-+		if (pic_ok_for_addr_p)
-+		{
-+			indirect_flag = 1;
-+			fprintf (file, "[");
-+		}
-+	}
-+
-+
-+	switch (GET_CODE (addr)) {
-+		case REG:
-+			regno = REGNO (addr);
-+			fprintf (file, ",%s", reg_names[regno]);
-+			break;
-+
-+		case PRE_DEC:
-+			regno = REGNO (XEXP (addr, 0));
-+			fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
-+			fprintf (file, "%s", reg_names[regno]);
-+			break;
-+
-+		case POST_INC:
-+			regno = REGNO (XEXP (addr, 0));
-+			fprintf (file, ",%s", reg_names[regno]);
-+			fputs (((last_mem_size == 1) ? "+" : "++"), file);
-+			break;
-+
-+		case PLUS:
-+			base = XEXP (addr, 0);
-+			if (MEM_P (base))
-+				base = XEXP (base, 0);
-+
-+			offset = XEXP (addr, 1);
-+			if (MEM_P (offset))
-+				offset = XEXP (offset, 0);
-+
-+			if ((CONSTANT_ADDRESS_P (base)) && (CONSTANT_ADDRESS_P (offset))) {
-+				if (!indirect_flag)
-+					check_direct_prefix_flag = 1;
-+				output_addr_const (file, base);
-+				check_direct_prefix_flag = 0;
-+				fputs ("+", file);
-+				output_addr_const (file, offset);
-+			}
-+
-+			else if ((CONSTANT_ADDRESS_P (base)) && (A_REG_P (offset))) {
-+				output_addr_const (file, base);
-+				fprintf (file, ",%s", reg_names[REGNO (offset)]);
-+			}
-+
-+			else if ((CONSTANT_ADDRESS_P (offset)) && (A_REG_P (base))) {
-+				output_addr_const (file, offset);
-+				fprintf (file, ",%s", reg_names[REGNO (base)]);
-+			}
-+
-+			/*** accumulator offset ***/
-+			else if (((D_REG_P (offset)) || (Q_REG_P (offset)))
-+			&& (A_REG_P (base))) {
-+				fprintf (file, "%s,%s",
-+				reg_names[REGNO (offset)], reg_names[REGNO (base)]);
-+			}
-+
-+			else if (((D_REG_P (base)) || (Q_REG_P (base)))
-+			&& (A_REG_P (offset))) {
-+				fprintf (file, "%s,%s",
-+				reg_names[REGNO (base)], reg_names[REGNO (offset)]);
-+			}
-+
-+			else if (GET_CODE (base) == PRE_DEC) {
-+				regno = REGNO (XEXP (base, 0));
-+				fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
-+				fprintf (file, "%s", reg_names[regno]);
-+			}
-+
-+			else
-+				abort ();
-+
-+			break;
-+
-+   default:
-+		/* Set this global before calling output_addr_const() */
-+		if (!indirect_flag)
-+			check_direct_prefix_flag = 1;
-+
-+		/* When printing a SYMBOL_REF in PIC mode, do not print the leading
-+		 * '#' and follow it by ',pcr' to enable relative addressing. */
-+		if (flag_pic && pic_ok_for_addr_p && GET_CODE (addr) == SYMBOL_REF)
-+		{
-+			ASM_OUTPUT_SYMBOL_REF (file, addr);
-+			fputs (",pcr", file);
-+			pic_ok_for_addr_p = 1;
-+		}
-+		else
-+		{
-+      	output_addr_const (file, addr);
-+		}
-+
-+		check_direct_prefix_flag = 0;
-+      break;
-+	}
-+
-+	if (indirect_flag)
-+		fprintf (file, "]");
-+}
-+
-+/*-------------------------------------------------------------------
-+    Update the CC Status
-+---------------------------------------------------------------------
-+   Set the cc_status for the results of an insn whose pattern is EXP.
-+   We assume that jumps don't affect the condition codes.
-+   All else, clobbers the condition codes, by assumption.
-+
-+   We assume that ALL add, minus, etc. instructions effect the condition
-+   codes.
-+-------------------------------------------------------------------*/
-+void
-+notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
-+{
-+	int src_code;
-+	int dst_code;
-+
-+	/*** recognize SET insn's ***/
-+	if (GET_CODE (exp) == SET)
-+	{
-+		src_code = GET_CODE (SET_SRC (exp));
-+		dst_code = GET_CODE (SET_DEST (exp));
-+
-+		/* Jumps do not alter the cc's.  */
-+		if (SET_DEST (exp) == pc_rtx)
-+			return;
-+
-+		/* Moving one register into another register (tfr):
-+		Doesn't alter the cc's.  */
-+		if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp))))
-+			return;
-+
-+		/* Moving memory into a register (load): Sets cc's. */
-+		if (REG_P (SET_DEST (exp)) && src_code == MEM) {
-+			cc_status.value1 = SET_SRC (exp);
-+			cc_status.value2 = SET_DEST (exp);
-+			return;
-+		}
-+
-+		/* Moving register into memory (store): Sets cc's. */
-+		if (dst_code == MEM && REG_P (SET_SRC (exp))) {
-+			cc_status.value1 = SET_SRC (exp);
-+			cc_status.value2 = SET_DEST (exp);
-+			return;
-+		}
-+
-+		/* Function calls clobber the cc's.  */
-+		else if (GET_CODE (SET_SRC (exp)) == CALL) {
-+			CC_STATUS_INIT;
-+			return;
-+		}
-+
-+		/* Tests and compares set the cc's in predictable ways.  */
-+		else if (SET_DEST (exp) == cc0_rtx)
-+		{
-+			cc_status.flags = 0;
-+			cc_status.value1 = SET_SRC (exp);
-+			cc_status.value2 = SET_DEST (exp);
-+			return;
-+		}
-+
-+		else if (A_REG_P (SET_DEST (exp)))
-+		{
-+			CC_STATUS_INIT;
-+			return;
-+		}
-+
-+		else
-+		{
-+			/* Certain instructions affect the condition codes. */
-+			switch (src_code)
-+			{
-+				case PLUS:
-+				case MINUS:
-+				case NEG:
-+				case ASHIFT:
-+					/* These instructions set the condition codes,
-+					 * and may modify the V bit. */
-+					cc_status.flags |= CC_NO_OVERFLOW;
-+					/* FALLTHRU */
-+
-+				case AND:
-+				case IOR:
-+				case XOR:
-+				case ASHIFTRT:
-+				case LSHIFTRT:
-+					/* These instructions set the condition codes,
-+					 * but cannot overflow (V=0). */
-+					cc_status.value1 = SET_SRC (exp);
-+					cc_status.value2 = SET_DEST (exp);
-+					break;
-+
-+				default:
-+					/* Everything else is clobbered */
-+					CC_STATUS_INIT;
-+			}
-+			return;
-+		}
-+	} /* SET */
-+
-+	else if (GET_CODE (exp) == PARALLEL
-+		&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
-+	{
-+		if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
-+			return;
-+		if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
-+		{
-+			CC_STATUS_INIT;
-+			cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
-+			return;
-+		}
-+	}
-+
-+	/*** default action if we haven't recognized something
-+	and returned earlier ***/
-+	CC_STATUS_INIT;
-+}
-+
-+
-+/** Returns nonzero if the expression EXP can be implemented using one
-+ * of the 6809's single operand instructions. */
-+int
-+m6809_single_operand_operator (rtx exp)
-+{
-+	rtx op1;
-+	HOST_WIDE_INT val;
-+	enum rtx_code code;
-+
-+	debug_rtx(exp);
-+
-+	code = GET_CODE (exp);
-+
-+	/* Unary operators always qualify */
-+	switch (code)
-+	{
-+		case NEG:
-+		case NOT:
-+			return 1;
-+
-+		default:
-+			break;
-+	}
-+
-+	/* Binary operators can only qualify if the second
-+	 * argument is a CONST_INT of certain value. */
-+	op1 = XEXP (exp, 1);
-+	if (GET_CODE (op1) != CONST_INT)
-+		return 0;
-+	val = INTVAL (op1);
-+	switch (code)
-+	{
-+		case PLUS:
-+		case MINUS:
-+			if (val == -1 || val == 1)
-+				return 1;
-+			break;
-+
-+		case ASHIFT:
-+		case ASHIFTRT:
-+		case LSHIFTRT:
-+		case ROTATE:
-+		case ROTATERT:
-+			if (val == 1)
-+				return 1;
-+			break;
-+
-+		default:
-+			break;
-+	}
-+
-+	return 0;
-+}
-+
-+
-+/** Return a bitarray of the hard registers which are used by a function. */
-+unsigned int
-+m6809_get_live_regs (void)
-+{
-+	unsigned int regs = 0;
-+	int regno;
-+
-+	if (frame_pointer_needed)
-+		regs |= (1 << HARD_FRAME_POINTER_REGNUM);
-+
-+	for (regno = HARD_X_REGNUM; regno <= HARD_U_REGNUM; regno++)
-+		if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
-+			regs |= (1 << regno);
-+
-+	return regs;
-+}
-+
-+
-+/** Return a printable version of a list of hard registers, suitable
-+ * for use in a PSHx or PULx insn. */
-+const char *
-+m6809_get_regs_printable (unsigned int regs)
-+{
-+	static char list[64];
-+	char *listp = list;
-+	unsigned int regno;
-+
-+	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
-+		if ((regs & (1 << regno)) && !S_REGNO_P (regno))
-+			listp += sprintf (listp,
-+				(listp == list) ? "%s" : ",%s", reg_names[regno]);
-+
-+	return list;
-+}
-+
-+
-+/** Return the total number of bytes covered by a set of hard registers. */
-+unsigned int
-+m6809_get_regs_size (unsigned int regs)
-+{
-+	unsigned int regno;
-+	unsigned int size = 0;
-+
-+	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
-+	{
-+		/* Only count register in the given register set */
-+		if (REGSET_CONTAINS_P (regno, regs))
-+		{
-+			/* Add 1 or 2 byte, depending on the size of the register.
-+			 * Since 'D' may be in both sets, check for WORD_REGSET first. */
-+			if (REGSET_CONTAINS_P(regno, WORD_REGSET))
-+				size += 2;
-+			else if (REGSET_CONTAINS_P(regno, BYTE_REGSET))
-+				size++;
-+		}
-+	}
-+	return size;
-+}
-+
-+
-+/* Given the target of call instruction in X,
-+ * return the tree node that contains the function declaration for
-+ * that target.
-+ *
-+ * If the rtx or the tree do not appear valid for any reason,
-+ * then return NULL_TREE.
-+ */
-+static tree call_target_decl (rtx x)
-+{
-+   tree decl;
-+
-+	/* Make sure the target is really a MEM. */
-+	if (!x || !MEM_P (x))
-+		return NULL_TREE;
-+
-+	/* Make sure the address is a SYMBOL_REF. */
-+	x = XEXP (x, 0);
-+	if (!x || (GET_CODE (x) != SYMBOL_REF))
-+		return NULL_TREE;
-+
-+	/* Get the declaration of this symbol */
-+	decl = SYMBOL_REF_DECL (x);
-+
-+	/* Make sure the declaration is really a function. */
-+	if (!decl || (TREE_CODE(decl) != FUNCTION_DECL))
-+		return NULL_TREE;
-+
-+   return decl;
-+}
-+
-+
-+/** Returns nonzero if a function, whose declaration is in DECL,
-+ * was declared to have the attribute given by ATTR_NAME. */
-+int
-+m6809_function_has_type_attr_p (tree decl, const char *attr_name)
-+{
-+	tree type;
-+
-+	type = TREE_TYPE (decl);
-+	return lookup_attribute (attr_name, TYPE_ATTRIBUTES (type)) != NULL;
-+}
-+
-+
-+
-+/** Returns nonzero if the current function was declared to have the
-+ * attribute given by ATTR_NAME. */
-+int
-+m6809_current_function_has_type_attr_p (const char *attr_name)
-+{
-+	return m6809_function_has_type_attr_p (current_function_decl, attr_name);
-+}
-+
-+
-+/** Return nonzero if the current function has no return value. */
-+int
-+m6809_current_function_is_void (void)
-+{
-+   return (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
-+}
-+
-+
-+/** Get the value of a declaration's 'bank', as set by the 'bank'
-+ * attribute.  If no bank was declared, it returns NULL by default. */
-+const char *
-+m6809_get_decl_bank (tree decl)
-+{
-+	tree attr;
-+
-+	/* Lookup the 'bank' attribute.  If it does not exist, then
-+	 * return NULL */
-+	attr = lookup_attribute ("bank", DECL_ATTRIBUTES (decl));
-+	if (attr == NULL_TREE)
-+		return NULL;
-+
-+	/* Make sure it has a value assigned to it */
-+	attr = TREE_VALUE (attr);
-+	if (attr == NULL_TREE)
-+	{
-+		warning (WARNING_OPT "banked function did not declare a bank number");
-+		return NULL;
-+	}
-+
-+	/* Return the bank name */
-+	attr = TREE_VALUE (attr);
-+	return TREE_STRING_POINTER (attr);
-+}
-+
-+
-+void
-+m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl)
-+{
-+	/* Check the function declaration for special properties.
-+	 *
-+	 * If the function was declare with __attribute__((bank)), output
-+	 * assembler definitions to force the function to go into the named
-+	 * bank.
-+	 */
-+	const char *bank_name = m6809_get_decl_bank (decl);
-+	if (bank_name != NULL)
-+	{
-+		/* Declare __self_bank as a local assembler value that denotes
-+		 * which bank the current function is in.  This is required only
-+		 * when the bank actually changes. */
-+		if (strcmp (bank_name, current_bank_name))
-+		{
-+			fprintf (asm_out_file, "__self_bank\t.equ %s\n", bank_name);
-+			strcpy (current_bank_name, bank_name);
-+		}
-+
-+		/* Declare a global assembler value that denotes which bank the
-+		 * named function is in. */
-+		fprintf (asm_out_file, "__%s_bank\t.gblequ %s\n", name, bank_name);
-+
-+		/* Force the current function into a new area */
-+		fprintf (asm_out_file, "\t.bank bank_%s (FSFX=_%s)\n",
-+			bank_name, bank_name);
-+		fprintf (asm_out_file, "\t.area bank_%s (BANK=bank_%s)\n",
-+			bank_name, bank_name);
-+	}
-+
-+	/* Emit the label for the function's name */
-+	ASM_OUTPUT_LABEL (asm_out_file, name);
-+}
-+
-+#if 0
-+/**
-+ * Handle pragmas.  Note that only the last branch pragma seen in the 
-+ * source has any affect on code generation.  
-+ */
-+
-+#define BAD_PRAGMA(msgid, arg) \
-+	do { warning (WARNING_OPT msgid, arg); return -1; } while (0)
-+
-+static int
-+pragma_parse (const char *name, tree *sect)
-+{
-+  tree s, x;
-+
-+  if (pragma_lex (&x) != CPP_OPEN_PAREN)
-+    BAD_PRAGMA ("missing '(' after '#pragma %s' - ignored", name);
-+
-+  if (pragma_lex (&s) != CPP_STRING)
-+    BAD_PRAGMA ("missing section name in '#pragma %s' - ignored", name);
-+
-+  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
-+    BAD_PRAGMA ("missing ')' for '#pragma %s' - ignored", name);
-+
-+  if (pragma_lex (&x) != CPP_EOF)
-+    warning (WARNING_OPT "junk at end of '#pragma %s'", name);
-+
-+  *sect = s;
-+  return 0;
-+}
-+
-+
-+/*
-+ * Handle #pragma section.
-+ * This is deprecated; code should use __attribute__(section("name"))
-+ * instead.
-+ */
-+void pragma_section (cpp_reader *pfile ATTRIBUTE_UNUSED)
-+{
-+	tree sect;
-+
-+	if (pragma_parse ("section", &sect))
-+		return;
-+
-+	snprintf (code_section_op, 6+TREE_STRING_LENGTH (sect),
-+		".area\t%s", TREE_STRING_POINTER (sect));
-+	snprintf (data_section_op, 6+TREE_STRING_LENGTH (sect),
-+		".area\t%s", TREE_STRING_POINTER (sect));
-+
-+	/* Mark a flag that sections have changed.  Upon emitting another
-+	 * declaration, the new .area directive will be written. */
-+	section_changed++;
-+}
-+#endif
-+
-+/**
-+ * Check a `double' value for validity for a particular machine mode.
-+ * Called by the CHECK_FLOAT_VALUE() machine-dependent macro.
-+ */
-+int
-+check_float_value (enum machine_mode mode, double *d, int overflow)
-+{
-+	if (mode == SFmode) {
-+		if (*d > 1.7014117331926443e+38) {
-+			error("magnitude of constant too large for `float'");
-+			*d = 1.7014117331926443e+38;
-+		}
-+		else if (*d < -1.7014117331926443e+38) {
-+			error("magnitude of constant too large for `float'");
-+			*d = -1.7014117331926443e+38;
-+		}
-+		else if ((*d > 0) && (*d < 2.9387358770557188e-39)) {
-+			warning(WARNING_OPT "`float' constant truncated to zero");
-+			*d = 0.0;
-+		}
-+		else if ((*d < 0) && (*d > -2.9387358770557188e-39)) {
-+			warning(WARNING_OPT "`float' constant truncated to zero");
-+			*d = 0.0;
-+		}
-+	}
-+	return overflow;
-+}
-+
-+
-+
-+/** Declare that the target supports named output sections. */
-+bool m6809_have_named_section = (bool)1;
-+
-+
-+/** Write to the assembler file a directive to place
-+ * subsequent objects to a different section in the
-+ * object file.  ASxxxx uses the "area" directive for
-+ * this purpose.  It does not however support generalized
-+ * alignment, and can only place items on an odd/even
-+ * boundary. */
-+void
-+m6809_asm_named_section (
-+	const char *name, 
-+	unsigned int flags ATTRIBUTE_UNUSED,
-+	tree decl)
-+{
-+	fprintf (asm_out_file, "\t.area\t%s\n", name);
-+}
-+
-+
-+enum reg_class
-+m6809_preferred_reload_class (rtx x, enum reg_class regclass)
-+{
-+	/* Check cases based on type code of rtx */
-+	switch (GET_CODE(x))
-+	{
-+		case CONST_INT:
-+		   /* Constants that can fit into 1 byte should be
-+			 * loaded into a Q_REGS reg */
-+			if (((unsigned) (INTVAL(x) + 0x80) < 0x100) &&
-+  				 (regclass > A_REGS))
-+      		return Q_REGS;
-+
-+			/* 16-bit constants should be loaded into A_REGS
-+			 * when possible.  gcc may already require A_REGS
-+			 * or D_REGS for certain types of instructions.
-+			 * This case applies mostly to simple copy operations
-+			 * to/from memory when any register will do, but
-+			 * it's best to avoid using D register since it is
-+			 * needed for other things.
-+			 */
-+			else if (((unsigned) (INTVAL(x) + 0x80) < 0x10000) &&
-+  				 (regclass > A_REGS))
-+      		return A_REGS;
-+			break;
-+
-+		case SYMBOL_REF:
-+		case LABEL_REF:
-+			/* Addresses should always be loaded into A_REGS */
-+			if (regclass >= A_REGS)
-+				return (A_REGS);
-+
-+		default:
-+			break;
-+	}
-+
-+	/* Check cases based on mode of rtx */
-+   if ((GET_MODE(x) == QImode) && (regclass != A_REGS))
-+      return Q_REGS;
-+
-+	/* Default: return whatever class reload suggested */
-+   return regclass;
-+}
-+
-+
-+/**
-+ * Check a new declaration for the "section" attribute.
-+ * If it exists, and the target section is "direct", then mark
-+ * the declaration (in RTL) to indicate special treatment.
-+ * When the variable is referenced later, we test for this flag
-+ * and can emit special asm text to force the assembler to use
-+ * short instructions.
-+ */
-+static void
-+m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED)
-+{
-+   tree attr, id;
-+   const char *name;
-+   const char *decl_name;
-+
-+   /* We only care about variable declarations, not functions */
-+   if (TREE_CODE (decl) != VAR_DECL)
-+      return;
-+
-+	/* For debugging purposes only; grab the decl's name */
-+   decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
-+
-+	/* Give up if the decl doesn't have any RTL */
-+   if (!DECL_RTL (decl))
-+      return;
-+
-+	/* See if it has a section attribute */
-+   attr = lookup_attribute ("section", DECL_ATTRIBUTES (decl));
-+   if (!attr)
-+      return;
-+
-+	/* See if the section attribute has a value */
-+   id = TREE_VALUE (TREE_VALUE (attr));
-+   if (!id)
-+      return;
-+   name = TREE_STRING_POINTER (id);
-+   if (!name)
-+      return;
-+
-+	/* See if the value is 'direct'.  If so, mark it. */
-+   if (!strcmp (name, "direct"))
-+      SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
-+}
-+
-+
-+/**
-+ * Output code to perform a complex shift, for which there is no
-+ * direct support in the instruction set.
-+ *
-+ * shift1 is an instruction pattern for performing a 1-bit modification.
-+ * This code wraps that pattern in a loop to perform the shift N times,
-+ * where N is given by the address register in operands[2].
-+ *
-+ * To support 16-bit shifts, shift2 can also be provided: it is
-+ * a second instruction to be included in the loop.  8-bit shift
-+ * insns will pass NULL here.
-+ *
-+ * The insn length of shift1/shift2 is assumed to be 1 byte,
-+ * which works in all of the cases it is needed so far.
-+ */
-+static void
-+m6809_gen_register_shift (
-+		rtx *operands,
-+		const char *shift1,
-+		const char *shift2 )
-+{
-+	char beq_pattern[32];
-+   char bra_pattern[32];
-+
-+	int shiftlen = (shift1 && shift2) ? 2 : 1;
-+	int cmplen = (REGNO (operands[2]) == HARD_X_REGNUM) ? 3 : 4;
-+
-+	int beq_offset = 2 + shiftlen + 2;
-+	int bra_offset = shiftlen + 2 + cmplen + 2;
-+
-+	sprintf (beq_pattern, "beq\t.+%d", beq_offset);
-+	sprintf (bra_pattern, "bra\t.-%d", bra_offset);
-+
-+	output_asm_insn ("pshs\t%2", operands);
-+	output_asm_insn ("lea%2\t-1,%2", operands);
-+   output_asm_insn ("cmp%2\t#-1", operands);
-+   output_asm_insn (beq_pattern, operands);
-+	if (shift1)
-+		output_asm_insn (shift1, operands);
-+	if (shift2)
-+		output_asm_insn (shift2, operands);
-+	output_asm_insn (bra_pattern, operands);
-+	output_asm_insn ("puls\t%2", operands);
-+}
-+
-+
-+/** Generate RTL for the upper 8-bits of a 16-bit constant. */
-+rtx
-+gen_rtx_const_high (rtx r)
-+{
-+   unsigned char v = (INTVAL (r) >> 8) & 0xFF;
-+	signed char s = (signed char)v;
-+   return gen_int_mode (s, QImode);
-+}
-+
-+
-+/** Generate RTL for the lower 8-bits of a 16-bit constant. */
-+rtx
-+gen_rtx_const_low (rtx r)
-+{
-+   unsigned char v = INTVAL (r) & 0xFF;
-+	signed char s = (signed char)v;
-+   return gen_int_mode (s, QImode);
-+}
-+
-+
-+/** Generate RTL to allocate/free bytes on the stack.
-+ * CODE is given as MINUS when allocating and PLUS when freeing,
-+ * to match the semantics of a downward-growing stack.  SIZE
-+ * is always given as a positive integer.
-+ */
-+static rtx
-+gen_rtx_stack_adjust (enum rtx_code code, int size)
-+{
-+	if (size <= 0)
-+		return NULL_RTX;
-+
-+	if (code == MINUS)
-+		size = -size;
-+
-+	return gen_rtx_SET (Pmode, stack_pointer_rtx, 
-+		gen_rtx_PLUS (Pmode, stack_pointer_rtx,
-+			gen_int_mode (size, HImode)));
-+}
-+
-+
-+/** Generate RTL to push/pop a set of registers. */
-+rtx
-+gen_rtx_register_pushpop (int op, int regs)
-+{
-+	rtx nregs = gen_int_mode (regs, QImode);
-+	
-+	if (op == UNSPEC_PUSH_RS)
-+		return gen_register_push (nregs);
-+	else
-+		return gen_register_pop (nregs);
-+}
-+
-+
-+/* Given a register set REGS, where the bit positions correspond to
-+ * hard register numbers, return another bitmask that represents the
-+ * order in which those registers would be pushed/popped.
-+ * Registers that are pushed first have higher bit positions.
-+ * The pop order is just the reverse bitmask.
-+ * These values are the same as the bitmasks actually used in the
-+ * machine instructions. */
-+static unsigned int
-+register_push_order (int regs)
-+{
-+	unsigned int order = 0;
-+
-+	if (REGSET_CONTAINS_P (HARD_PC_REGNUM, regs))
-+		order |= 0x80;
-+	if (REGSET_CONTAINS_P (HARD_U_REGNUM, regs))
-+		order |= 0x40;
-+	if (REGSET_CONTAINS_P (HARD_Y_REGNUM, regs))
-+		order |= 0x20;
-+	if (REGSET_CONTAINS_P (HARD_X_REGNUM, regs))
-+		order |= 0x10;
-+	if (REGSET_CONTAINS_P (HARD_DP_REGNUM, regs))
-+		order |= 0x8;
-+	if (REGSET_CONTAINS_P (HARD_B_REGNUM, regs))
-+		order |= 0x4;
-+	if (REGSET_CONTAINS_P (HARD_A_REGNUM, regs))
-+		order |= 0x2;
-+	if (REGSET_CONTAINS_P (HARD_CC_REGNUM, regs))
-+		order |= 0x1;
-+
-+	if (REGSET_CONTAINS_P (HARD_D_REGNUM, regs))
-+		order |= (0x4 | 0x2);
-+	return order;
-+}
-+
-+
-+/* Returns nonzero if two consecutive push or pop instructions,
-+ * as determined by the OP, can be merged into a single instruction.
-+ * The first instruction in the sequence pushes/pops REGS1; the
-+ * second applies to REGS2.
-+ *
-+ * If true, the resulting instruction can use (regs1 | regs2)
-+ * safely.
-+ */
-+int
-+m6809_can_merge_pushpop_p (int op, int regs1, int regs2)
-+{
-+	/* Register sets must not overlap */
-+	if (regs1 & regs2)
-+		return 0;
-+
-+	if (op == UNSPEC_PUSH_RS)
-+		return (register_push_order (regs1) > register_push_order (regs2));
-+	else if (op == UNSPEC_POP_RS)
-+		return (register_push_order (regs1) < register_push_order (regs2));
-+	else
-+		return 0;
-+}
-+
-+
-+/** Emit instructions for making a library call.
-+ * MODE is the mode of the operation.
-+ * NAME is the library function name.
-+ * OPERANDS is the rtx array provided by the recognizer.
-+ * COUNT is the number of input operands to the call, and
-+ * should be 1 for a unary op or 2 for a binary op.
-+ */
-+void
-+emit_libcall_insns (enum machine_mode mode, 
-+	const char *name, 
-+	rtx *operands,
-+	int count)
-+{
-+	/* Generate an rtx for the call target. */
-+	rtx symbol = gen_rtx_SYMBOL_REF (Pmode, name);
-+
-+	/* Emit the library call.  Slightly different based
-+	on the number of operands */
-+	if (count == 2)
-+		emit_library_call (symbol, LCT_NORMAL, mode,
-+			2, operands[1], mode, operands[2], mode);
-+	else
-+		emit_library_call (symbol, LCT_NORMAL, mode,
-+			1, operands[1], mode);
-+
-+	/* The library call is expected to put its result
-+	in LIBCALL_VALUE, so need to copy it into the destination. */
-+	emit_move_insn (operands[0], LIBCALL_VALUE(mode));
-+}
-+
-+
-+/**
-+ * A small helper function that writes out a single branch instruction.
-+ * OPCODE is the short name, e.g. "ble".
-+ * OPERANDS has the rtx for the target label.
-+ * LONG_P is nonzero if we are emitting a long branch, and need to
-+ * prepend an 'l' to the opcode name.
-+ */
-+void output_branch_insn1 (const char *opcode, rtx *operands, int long_p)
-+{
-+	char pattern[64];
-+	sprintf (pattern, "%s%s\t%%l0", long_p ? "l" : "", opcode);
-+	output_asm_insn (pattern, operands);
-+}
-+
-+/**
-+ * Output a branch/conditional branch insn of the proper
-+ * length.  code identifies the particular branch insn.
-+ * operands holds the branch target in operands[0].
-+ * length says what the size of this insn should be.
-+ * Based on the length, we know whether it should be a
-+ * short (8-bit) or long (16-bit) branch.
-+ */
-+const char *
-+output_branch_insn (enum rtx_code code, rtx *operands, int length)
-+{
-+	int shortform; 
-+
-+	/* Decide whether or not to use the long or short form.
-+	 * Calculate automatically based on insn lengths. */
-+   shortform = ((length > 2) ? 0 : 1);
-+
-+	/* Determine the proper opcode.
-+	 * Use the short (2-byte) opcode if the target is within
-+	 * reach.  Otherwise, use jmp (3-byte opcode), unless
-+	 * compiling with -fpic, in which case we'll need to use
-+	 * lbra (4-byte opcode).
-+	 */
-+	switch (code)
-+	{
-+		case LABEL_REF: 
-+			if (shortform)
-+				output_branch_insn1 ("bra", operands, 0);
-+			else if (flag_pic)
-+				output_branch_insn1 ("bra", operands, 1);
-+			else
-+				output_branch_insn1 ("jmp", operands, 0);
-+			break;
-+		case EQ:
-+			output_branch_insn1 ("beq", operands, !shortform);
-+			break;
-+		case NE:
-+			output_branch_insn1 ("bne", operands, !shortform);
-+			break;
-+		case GT:
-+			output_branch_insn1 ("bgt", operands, !shortform);
-+			break;
-+		case GTU:
-+			output_branch_insn1 ("bhi", operands, !shortform);
-+			break;
-+		case LT:
-+			if (cc_prev_status.flags & CC_NO_OVERFLOW)
-+			{
-+				output_branch_insn1 ("bmi", operands, !shortform);
-+			}
-+			else
-+			{
-+				output_branch_insn1 ("blt", operands, !shortform);
-+			}
-+			break;
-+		case LTU:
-+			output_branch_insn1 ("blo", operands, !shortform);
-+			break;
-+		case GE:
-+			if (cc_prev_status.flags & CC_NO_OVERFLOW)
-+			{
-+				output_branch_insn1 ("bpl", operands, !shortform);
-+			}
-+			else
-+			{
-+				output_branch_insn1 ("bge", operands, !shortform);
-+			}
-+			break;
-+		case GEU:
-+			output_branch_insn1 ("bhs", operands, !shortform);
-+			break;
-+		case LE:
-+			if (cc_prev_status.flags & CC_NO_OVERFLOW)
-+			{
-+				output_branch_insn1 ("bmi", operands, !shortform);
-+				output_branch_insn1 ("beq", operands, !shortform);
-+			}
-+			else
-+			{
-+				output_branch_insn1 ("ble", operands, !shortform);
-+			}
-+			break;
-+		case LEU:
-+			output_branch_insn1 ("bls", operands, !shortform);
-+			break;
-+		default:
-+			abort();
-+			break;
-+	}
-+	return "";
-+}
-+
-+
-+/** Returns the "cost" of an RTL expression.
-+ * In general, the expression "COSTS_N_INSNS(1)" is used to represent
-+ * the cost of a fast 8-bit arithmetic instruction that operates on
-+ * a reg/mem or a reg/immed.  Other costs are relative to this.
-+ *
-+ * Notes:
-+ * - The cost of a REG is always zero; this cannot be changed.
-+ *
-+ * - On the 6809, instructions on two registers will nearly always take
-+ *   longer than those that operate on a register and a constant/memory,
-+ *   because of the way the instruction set is structured.
-+ *
-+ * TODO: multiply HImode by 2 should be done via shifts, instead of add.
-+ */
-+static bool
-+m6809_rtx_costs (rtx X, int code, int outer_code ATTRIBUTE_UNUSED,
-+	int *total, bool speed)
-+{
-+	int has_const_arg = 0;
-+	HOST_WIDE_INT const_arg;
-+	enum machine_mode mode;
-+	int nargs = 1;
-+	rtx op0, op1;
-+
-+	/* Data RTXs return a value between 0-3, depending on complexity.
-+	All of these are less than COSTS_N_INSNS(1). */
-+	switch (code)
-+	{
-+		case CC0:
-+		case PC:
-+			*total = 0;
-+			return true;
-+
-+ 		case CONST_INT:
-+    		if (X == const0_rtx)
-+			{
-+				*total = 0;
-+				return true;
-+			}
-+			else if ((unsigned) INTVAL (X) < 077) 
-+			{
-+				*total = 1;
-+				return true;
-+			}
-+			else
-+			{
-+				*total = 2;
-+				return true;
-+			}
-+
-+ 		case LABEL_REF: case CONST:
-+   		*total = 2;
-+			return true;
-+
-+ 		case SYMBOL_REF:
-+			/* References to memory are made cheaper if they have
-+			 * the 'direct' mode attribute set */
-+			*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
-+			return true;
-+
-+		case MEM:
-+			/* See what form of address was given */
-+			X = XEXP (X, 0);
-+			switch (GET_CODE (X))
-+			{
-+ 				case SYMBOL_REF:
-+					*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
-+					break;
-+
-+				case CONST_INT:
-+					*total = 2;
-+					break;
-+
-+				case MEM:
-+					*total = COSTS_N_INSNS (1) + 2;
-+					break;
-+
-+				default:
-+					break;
-+			}
-+			return true;
-+
-+ 		case CONST_DOUBLE:
-+			/* TODO : not sure about this value. */
-+   		*total = 3;
-+			return true;
-+
-+		default:
-+			break;
-+	}
-+
-+	/* Decode the rtx */
-+	mode = GET_MODE (X);
-+	op0 = XEXP (X, 0);
-+	op1 = XEXP (X, 1);
-+
-+	/* We don't implement anything in SImode or greater. */
-+	if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (SImode))
-+	{
-+		*total = COSTS_N_INSNS (100);
-+		return true;
-+	}
-+
-+	/* Figure out if there is a constant argument, and its value. */
-+	if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
-+		|| GET_RTX_CLASS (code) == RTX_COMM_ARITH)
-+	{
-+		nargs = 2;
-+		if (GET_CODE (op1) == CONST_INT)
-+		{
-+			has_const_arg = 1;
-+			const_arg = INTVAL (op1);
-+		}
-+	}
-+
-+	/* Penalize a reg/reg operation by adding MEMORY_MOVE_COST,
-+	 * Ignore soft registers, since these are really in memory.
-+	 *
-+	 * TODO: penalize HImode reg/reg for most operations, except maybe
-+	 * additions since index registers allow for that.
-+	 *
-+	 * TODO: shifts by constant N do not always require N instructions;
-+	 * some of this can be done cheaper.  The number of actual insns can be
-+	 * predicted well.
-+	 */
-+	if (nargs == 2 && REAL_REG_P (op0) && REAL_REG_P (op1))
-+	{
-+		*total = MEMORY_MOVE_COST (mode, Q_REGS, 0);
-+	}
-+	else
-+	{
-+		*total = 0;
-+	}
-+
-+	/* Operator RTXs are counted as COSTS_N_INSNS(N), where N is
-+	the estimated number of actual machine instructions needed to
-+	perform the computation.  Some small adjustments are made since
-+	some "instructions" are more complex than others. */
-+	switch (code)
-+	{
-+		case PLUS: case MINUS: case COMPARE:
-+			/* 6809 handles these natively in QImode, and in HImode as long
-+			 * as operand 1 is constant. */
-+			if (mode == QImode || (mode == HImode && has_const_arg))
-+				*total += COSTS_N_INSNS (1);
-+			else 
-+				*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
-+
-+			/* -1, 0, and 1 can be done using inherent instructions
-+			 * for PLUS and MINUS in QImode, so don't add extra cost. */
-+  			if (has_const_arg
-+				&& (mode == QImode || mode == HImode)
-+				&& (const_arg == -1 || const_arg == 0 || const_arg == 1)
-+				&& (code == PLUS || code == MINUS))
-+			{
-+				return true;
-+			}
-+			break;
-+
-+		case AND: case IOR: case XOR:
-+		case NEG: case NOT:
-+			/* 6809 handles these natively in QImode, but requires
-+			 * splitting in HImode.   Treat these as 2 insns. */
-+			*total += COSTS_N_INSNS (1) * GET_MODE_SIZE (mode);
-+			break;
-+
-+  		case ASHIFT: case ASHIFTRT: case LSHIFTRT:
-+  		case ROTATE: case ROTATERT:
-+			/* 6809 can do shift/rotates of a QImode by a constant in
-+			 * 1 insn times the shift count, or in HImode by a constant 
-+			 * by splitting to 2 insns.
-+			 *
-+			 * Shift by a nonconstant will take significantly longer
-+			 * than any of these. */
-+  			if (has_const_arg)
-+			{
-+				const_arg %= (GET_MODE_SIZE (mode) * 8);
-+				if (const_arg == 0)
-+				{
-+					*total += COSTS_N_INSNS(1);
-+					return true;
-+				}
-+
-+				/* HImode shifts greater than 8 get optimized due
-+				 * to register transfer from b to a; this cuts down the
-+				 * cost. */
-+				if (const_arg >= 8)
-+				{
-+					*total += COSTS_N_INSNS (1);
-+					const_arg -= 8;
-+				}
-+
-+				/* The computed cost is 'const_arg' 1-bit shifts, doubled
-+				if in HImode, minus the cost of the constant itself which
-+				will be added in later but really shouldn't be. */
-+				*total += COSTS_N_INSNS (const_arg) * GET_MODE_SIZE (mode) - 1;
-+				return true;
-+			}
-+			else
-+			{
-+				/* It may take up to 7 iterations of about 6-7 real
-+				 * instructions, so make this expensive. */
-+				*total += COSTS_N_INSNS (50);
-+			}
-+  			break;
-+
-+		case MULT:
-+ 		{
-+ 			/* Multiply is cheap when both arguments are 8-bits.  They
-+ 			could be QImode, or QImode widened to HImode, or a constant
-+ 			that fits into 8-bits.  As long as both operands qualify,
-+ 			we can use a single mul instruction.
-+  
-+ 			Assume that fast multiply can be used, and change this if we find
-+ 			differently... */
-+ 			int ok_for_qihi3 = 1;
-+  
-+ 			/* Check the first operand */	
-+ 			switch (GET_MODE (op0))
-+ 			{
-+ 				case QImode:
-+ 					break;
-+ 				case HImode:
-+ 					if (GET_CODE (op0) != SIGN_EXTEND && GET_CODE (op0) != ZERO_EXTEND)
-+  						ok_for_qihi3 = 0;
-+ 					break;
-+ 				default:
-+ 					ok_for_qihi3 = 0;
-+ 					break;
-+  			}
-+ 
-+			/* Likewise, check the second operand.  This is where constants may appear. */
-+ 			switch (GET_MODE (op1))
-+ 			{
-+ 				case QImode:
-+ 					break;
-+ 				case HImode:
-+					if (GET_CODE (op1) != SIGN_EXTEND && GET_CODE (op1) != ZERO_EXTEND)
-+ 						ok_for_qihi3 = 0;
-+ 					break;
-+ 				case VOIDmode:
-+					if (!CONST_OK_FOR_LETTER_P (const_arg, 'K'))
-+ 						ok_for_qihi3 = 0;
-+					break;
-+ 				default:
-+ 					ok_for_qihi3 = 0;
-+ 					break;
-+ 			}
-+ 
-+ 			/* Fast multiply takes about 4 times as many cycles as a normal
-+ 			arithmetic operation.  Otherwise, it will take an expensive libcall. */
-+ 			if (ok_for_qihi3)
-+ 				*total += COSTS_N_INSNS (4);
-+ 			else
-+ 				*total = COSTS_N_INSNS (50);
-+  	  		break;
-+ 		}
-+
-+		case DIV: case UDIV: case MOD: case UMOD:
-+			/* These all require more expensive libcalls. */
-+			*total += COSTS_N_INSNS (100);
-+  			break;
-+
-+		/* TODO : TRUNCATE, SIGN_EXTEND, and ZERO_EXTEND */
-+
-+		/* These can normally be done with autoincrement, etc., so
-+		 * don't charge for them. */
-+		case PRE_DEC:
-+		case PRE_INC:
-+		case POST_DEC:
-+		case POST_INC:
-+			break;
-+
-+		default:
-+			break;
-+	}
-+
-+	/* Always return false, and let the caller gather the costs
-+	 * of the operands */
-+	return false;
-+}
-+
-+
-+static tree
-+m6809_handle_fntype_attribute (tree *node, tree name,
-+	tree args ATTRIBUTE_UNUSED,
-+	int flags ATTRIBUTE_UNUSED,
-+	bool *no_add_attrs)
-+{
-+	if (TREE_CODE (*node) != FUNCTION_TYPE)
-+	{
-+		warning (WARNING_OPT "'%s' only valid for functions", 
-+			IDENTIFIER_POINTER (name));
-+		*no_add_attrs = TRUE;
-+	}
-+
-+	return NULL_TREE;
-+}
-+
-+
-+static tree
-+m6809_handle_data_type_attribute (tree *node ATTRIBUTE_UNUSED,
-+	tree name ATTRIBUTE_UNUSED,
-+	tree args ATTRIBUTE_UNUSED,
-+	int flags ATTRIBUTE_UNUSED,
-+	bool *no_add_attrs ATTRIBUTE_UNUSED)
-+{
-+	return NULL_TREE;
-+}
-+
-+
-+
-+static tree
-+m6809_handle_default_attribute (tree *node ATTRIBUTE_UNUSED, 
-+	tree name ATTRIBUTE_UNUSED,
-+	tree args ATTRIBUTE_UNUSED,
-+	int flags ATTRIBUTE_UNUSED,
-+	bool *no_add_attrs ATTRIBUTE_UNUSED )
-+{
-+	return NULL_TREE;
-+}
-+
-+
-+/* Table of valid machine attributes */
-+const struct attribute_spec m6809_attribute_table[] = { /*
-+{ name,        min, max, decl,  type, fntype, handler } */
-+{ "interrupt", 0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
-+{ "naked",     0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
-+{ "far",       0,   1,   false, true,  true,  m6809_handle_fntype_attribute },
-+{ "bank",      0,   1,   true,  false, false, m6809_handle_default_attribute },
-+{ "boolean",   0,   0,   false, true,  false, m6809_handle_data_type_attribute },
-+{ NULL,        0,   0,   false, true,  false, NULL },
-+};
-+
-+
-+/** Initialize builtin routines for the 6809. */
-+void
-+m6809_init_builtins (void)
-+{
-+	/* Create type trees for each function signature required.
-+	 *
-+	 * void_ftype_void = void f(void)
-+	 * void_ftype_uchar = void f(unsigned char)
-+	 * uchar_ftype_uchar2 = unsigned char f (unsigned char, unsigned char)
-+	 */
-+	tree void_ftype_void = 
-+		build_function_type (void_type_node, void_list_node);
-+
-+	tree void_ftype_uchar =
-+		build_function_type (void_type_node,
-+			tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node));
-+
-+	tree uchar_ftype_uchar2 =
-+		build_function_type (unsigned_char_type_node,
-+			tree_cons (NULL_TREE, unsigned_char_type_node, 
-+				tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node)));
-+
-+	/* Register each builtin function. */
-+	add_builtin_function ("__builtin_swi", void_ftype_void,
-+		M6809_SWI, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_swi2", void_ftype_void,
-+		M6809_SWI2, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_swi3", void_ftype_void,
-+		M6809_SWI3, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_cwai", void_ftype_uchar,
-+		M6809_CWAI, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_sync", void_ftype_void,
-+		M6809_SYNC, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_nop", void_ftype_void,
-+		M6809_NOP, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_blockage", void_ftype_void,
-+		M6809_BLOCKAGE, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_add_decimal", uchar_ftype_uchar2,
-+		M6809_ADD_DECIMAL, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_add_carry", uchar_ftype_uchar2,
-+		M6809_ADD_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
-+
-+	add_builtin_function ("__builtin_sub_carry", uchar_ftype_uchar2,
-+		M6809_SUB_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
-+}
-+
-+
-+/** Used by m6809_expand_builtin, given a tree ARGLIST which
-+ * refers to the operands of a builtin call, return an rtx
-+ * that represents the nth operand, as denoted by OPNUM, which
-+ * is a zero-based integer.  MODE gives the expected mode
-+ * of the operand.
-+ *
-+ * This rtx is suitable for use in the emitted RTL for the
-+ * builtin instruction. */
-+rtx
-+m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum)
-+{
-+	tree arg;
-+	rtx r;
-+
-+	arg = CALL_EXPR_ARG (arglist, opnum);
-+
-+	/* Convert the tree to RTL */
-+	r = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
-+	if (r == NULL_RTX)
-+		return NULL_RTX;
-+	return r;
-+}
-+
-+
-+/** Expand a builtin that was registered in init_builtins into
-+ * RTL.  */
-+rtx
-+m6809_expand_builtin (tree exp, 
-+	rtx target, 
-+	rtx subtarget ATTRIBUTE_UNUSED,
-+	enum machine_mode mode ATTRIBUTE_UNUSED,
-+	int ignore ATTRIBUTE_UNUSED )
-+{
-+   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
-+	tree arglist = exp;
-+	unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
-+	rtx r0, r1;
-+
-+	switch (fcode)
-+	{
-+		case M6809_SWI:
-+			r0 = gen_rtx_CONST_INT (VOIDmode, 1);
-+			emit_insn (target = gen_m6809_swi (r0));
-+			return target;
-+
-+		case M6809_SWI2:
-+			r0 = gen_rtx_CONST_INT (VOIDmode, 2);
-+			emit_insn (target = gen_m6809_swi (r0));
-+			return target;
-+
-+		case M6809_SWI3:
-+			r0 = gen_rtx_CONST_INT (VOIDmode, 3);
-+			emit_insn (target = gen_m6809_swi (r0));
-+			return target;
-+
-+		case M6809_CWAI:
-+			r0 = m6809_builtin_operand (arglist, QImode, 0);
-+			emit_insn (target = gen_m6809_cwai (r0));
-+			return target;
-+
-+		case M6809_SYNC:
-+			emit_insn (target = gen_m6809_sync ());
-+			return target;
-+
-+		case M6809_ADD_CARRY:
-+			r0 = m6809_builtin_operand (arglist, QImode, 0);
-+			r1 = m6809_builtin_operand (arglist, QImode, 1);
-+			if (!target)
-+				target = gen_reg_rtx (QImode);
-+			emit_insn (gen_addqi3_carry (target, r0, r1));
-+			return target;
-+
-+		case M6809_SUB_CARRY:
-+			r0 = m6809_builtin_operand (arglist, QImode, 0);
-+			r1 = m6809_builtin_operand (arglist, QImode, 1);
-+			if (!target)
-+				target = gen_reg_rtx (QImode);
-+			emit_insn (gen_subqi3_carry (target, r0, r1));
-+			return target;
-+
-+		case M6809_NOP:
-+			emit_insn (target = gen_nop ());
-+			return target;
-+
-+		case M6809_BLOCKAGE:
-+			emit_insn (target = gen_blockage ());
-+			return target;
-+
-+		case M6809_ADD_DECIMAL:
-+			r0 = m6809_builtin_operand (arglist, QImode, 0);
-+			r1 = m6809_builtin_operand (arglist, QImode, 1);
-+			if (!target)
-+				target = gen_reg_rtx (QImode);
-+			emit_insn (gen_addqi3_decimal (target, r0, r1));
-+			return target;
-+
-+		default:
-+			warning (WARNING_OPT "unknown builtin expansion ignored");
-+			return NULL_RTX;
-+	}
-+}
-+
-+
-+
-+/* Returns nonzero if 'x' represents a function that was declared
-+ * as __noreturn__. */
-+int
-+noreturn_functionp (rtx x)
-+{
-+	tree decl = call_target_decl (x);
-+
-+	if (decl == NULL_TREE)
-+		return 0;
-+	else
-+		return TREE_THIS_VOLATILE (decl);
-+}
-+
-+
-+const char *
-+far_function_type_p (tree type)
-+{
-+	tree attr;
-+	const char *page;
-+
-+	/* Return whether or not this decl has the far attribute */
-+	attr = lookup_attribute ("far", TYPE_ATTRIBUTES (type));
-+	if (attr == NULL_TREE)
-+		return NULL;
-+
-+	/* If it is far, check for a value */
-+	attr = TREE_VALUE (attr);
-+	if (attr == NULL_TREE)
-+	{
-+		warning (WARNING_OPT "far code page not specified, using local value");
-+		return far_code_page;
-+	}
-+
-+	/* We have a TREE_LIST of attribute values, get the first one.
-+	 * It should be an INTEGER_CST. */
-+	attr = TREE_VALUE (attr);
-+	page = TREE_STRING_POINTER (attr);
-+	return page;
-+}
-+
-+
-+/* For a far function, returns the identifier that states which page
-+ * it resides in.  Otherwise, returns NULL for ordinary functions. */
-+const char *
-+far_functionp (rtx x)
-+{
-+	tree decl, decl_type;
-+	const char *page;
-+
-+	/* Find the FUNCTION_DECL corresponding to the rtx being called. */
-+	decl = call_target_decl (x);
-+	if (decl == NULL_TREE)
-+		return NULL;
-+
-+	/* See if the function has the new 'banked' attribute.  These
-+	 * are numeric instead of text */
-+	page = m6809_get_decl_bank (decl);
-+	if (page)
-+		return page;
-+
-+	/* No, lookup the type of the function and see if the type
-+	 * specifies far or not. */
-+	decl_type = TREE_TYPE (decl);
-+	if (decl_type == NULL_TREE)
-+		return NULL;
-+	return far_function_type_p (decl_type);
-+}
-+
-+
-+
-+/** Outputs the assembly language for a far call. */
-+void
-+output_far_call_insn (rtx *operands, int has_return)
-+{
-+	static char page_data[64];
-+	const char *called_page;
-+
-+  /* The logic is the same for functions whether or not there
-+	* is a return value.  Skip over the return value in this
-+	* case, so that the call location is always operands[0].  */
-+  if (has_return)
-+	  operands++;
-+
-+  /* Get the name of the page being called */
-+  called_page = far_functionp (operands[0]);
-+
-+#if 0 /* TODO : broken logic */
-+  /* See if the called page name is a 'bank' */
-+  if (isdigit (*called_page))
-+  {
-+    /* New style banking */
-+	 if (!strcmp (called_page, current_bank_name))
-+	 {
-+	 	/* Same page */
-+  	  	output_asm_insn ("jsr\t%0", operands);
-+	 }
-+	 else
-+	 {
-+	 	/* Different page */
-+		output_asm_insn ("jsr\t__far_call_handler\t;new style", operands);
-+  	  	output_asm_insn ("\t.dw\t%0", operands);
-+		sprintf (page_data, "\t.db\t%s", called_page);
-+	 	output_asm_insn (page_data, operands);
-+	 }
-+	 return;
-+  }
-+#endif
-+
-+  /* Are we calling a different page than we are running in? */
-+  if (!strcmp (called_page, far_code_page))
-+  {
-+    /* Same page : no need to execute a far call */
-+		if (flag_pic)
-+			output_asm_insn ("lbsr\t%C0", operands);
-+		else
-+			output_asm_insn ("jsr\t%0", operands);
-+  }
-+  else
-+  {
-+    /* Different page : need to emit far call thunk */
-+
-+    /* First output a call to the thunk for making far calls. */
-+		if (flag_pic)
-+			output_asm_insn ("lbsr\t__far_call_handler", operands);
-+		else
-+			output_asm_insn ("jsr\t__far_call_handler\t;old style", operands);
-+  
-+    /* Now output the name of the call site */
-+    output_asm_insn ("\t.dw\t%C0", operands);
-+  
-+    /* Finally output the page number */
-+    sprintf (page_data, "\t.db\t%s", far_functionp (operands[0]));
-+    output_asm_insn (page_data, operands);
-+  }
-+}
-+
-+
-+int
-+m6809_init_cumulative_args (CUMULATIVE_ARGS cum ATTRIBUTE_UNUSED,
-+     tree fntype,
-+     rtx libname ATTRIBUTE_UNUSED)
-+{
-+	cum = 0;
-+
-+	/* For far functions, the current implementation does not allow for
-+	 * stack parameters.  So note whenever the called function is far
-+	 * and in a different page than the current one; such a function
-+	 * should give an error if a stack parameter is generated. */
-+	if (fntype)
-+	{
-+		const char *called_page = far_function_type_p (fntype);
-+		if (called_page && strcmp (called_page, far_code_page) && !TARGET_FAR_STACK_PARAM)
-+			cum |= CUM_STACK_INVALID;
-+	}
-+
-+	if (fntype && TYPE_ARG_TYPES (fntype) != 0 &&
-+		(TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
-+	{
-+		/* has variable arguments, cannot use registers */
-+		cum |= (CUM_X_MASK | CUM_B_MASK | CUM_STACK_ONLY);
-+	}
-+
-+	if (m6809_abi_version == M6809_ABI_VERSION_STACK)
-+	{
-+		/* cannot use registers ; only use the stack */
-+		cum |= (CUM_STACK_ONLY | CUM_X_MASK | CUM_B_MASK);
-+	}
-+
-+	return cum;
-+}
-+
-+
-+rtx
-+m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump)
-+{
-+	if (*cump & CUM_STACK_INVALID)
-+	{
-+		*cump &= ~CUM_STACK_INVALID;
-+		error ("far function needs stack, will not work");
-+	}
-+	return NULL_RTX;
-+}
-+
-+void m6809_asm_trampoline_template(FILE *f)
-+{
-+	fprintf(f, "ldy #0000\n");
-+	fprintf(f, "jmp 0x0000\n");
-+}
-+
-+/*
-+ * Trampoline output:
-+ *
-+ * ldu #&cxt      4 bytes   --LDY- ?? ??
-+ * jmp fnaddr     3 bytes   JMP ?? ??
-+ */
-+void
-+m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
-+{
-+	rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
-+	/* TODO - optimize by generating the entire trampoline code here,
-+	 * and removing the template altogether, since there are only two
-+	 * bytes there that matter. */
-+	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);
-+	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 5)), fnaddr);
-+}
-+
-+
-+/** Echo the version of the compiler and the name of the source file
-+ * at the beginning of each assembler output file.  asm_out_file
-+ * is a global FILE * pointing to the output stream. */
-+void
-+m6809_asm_file_start (void)
-+{
-+	const char *module_name;
-+
-+	fprintf (asm_out_file, "\n;;; gcc for m6809 : %s %s\n",
-+		__DATE__, __TIME__);
-+	fprintf (asm_out_file, ";;; %s\n", version_string);
-+
-+	fprintf (asm_out_file, ";;; ABI version %d\n", m6809_abi_version);
-+	fprintf (asm_out_file, ";;; %s\n",
-+		(TARGET_BYTE_INT ? "-mint8" : "-mint16"));
-+	if (TARGET_EXPERIMENT)
-+		fprintf (asm_out_file, ";;; -mexperiment\n");
-+	if (TARGET_WPC)
-+		fprintf (asm_out_file, ";;; -mwpc\n");
-+	if (TARGET_6309)
-+		fprintf (asm_out_file, ";;; -m6309\n");
-+
-+	/* Print the name of the module, which is taken as the base name
-+	 * of the input file.
-+	 * See the 'User-Defined Symbols' section of the assembler
-+	 * documentation for the rules on valid symbols.
-+	 */
-+	module_name = lbasename (main_input_filename);
-+
-+	fprintf (asm_out_file, "\t.module\t");
-+
-+	if (*module_name >= '0' && *module_name <= '9')
-+		fprintf (asm_out_file, "_");
-+
-+	while (*module_name)
-+	{
-+		if ((*module_name >= '0' && *module_name <= '9')
-+			|| (*module_name >= 'A' && *module_name <= 'Z')
-+			|| (*module_name >= 'a' && *module_name <= 'z')
-+			|| *module_name == '$'
-+			|| *module_name == '.'
-+			|| *module_name == '_')
-+		{
-+			fprintf (asm_out_file, "%c", *module_name);
-+		}
-+		else
-+		{
-+			fprintf (asm_out_file, "_");
-+		}
-+		module_name++;
-+	}
-+
-+	fprintf (asm_out_file, "\n");
-+}
-+
-+
-+/** Returns true if prologue/epilogue code is required for the
-+ * current function being compiled.
-+ *
-+ * This is just the inverse of whether the function is declared as
-+ * 'naked'.
-+ */
-+int
-+prologue_epilogue_required (void)
-+{
-+	return !m6809_current_function_has_type_attr_p ("naked")
-+		&& !m6809_current_function_has_type_attr_p ("noreturn");
-+}
-+
-+
-+/** Expand RTL for function entry */
-+void
-+emit_prologue_insns (void)
-+{
-+  rtx insn;
-+  unsigned int live_regs = m6809_get_live_regs ();
-+  unsigned int frame_size = get_frame_size ();
-+
-+  /* Save all registers used, including the frame pointer */
-+  if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
-+  {
-+    insn = emit_insn (
-+      gen_rtx_register_pushpop (UNSPEC_PUSH_RS, live_regs));
-+    RTX_FRAME_RELATED_P (insn) = 1;
-+  }
-+
-+  /* Allocate space for local variables */
-+  if (frame_size != 0)
-+  {
-+    insn = emit_insn (gen_rtx_stack_adjust (MINUS, frame_size));
-+    RTX_FRAME_RELATED_P (insn) = 1;
-+  }
-+
-+  /* Set the frame pointer if it is needed */
-+  if (frame_pointer_needed)
-+  {
-+    insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
-+    RTX_FRAME_RELATED_P (insn) = 1;
-+  }
-+}
-+
-+
-+/** Expand RTL for function exit */
-+void
-+emit_epilogue_insns (bool sibcall_p)
-+{
-+  unsigned int live_regs = m6809_get_live_regs ();
-+  unsigned int frame_size = get_frame_size ();
-+
-+  if (frame_size != 0)
-+    emit_insn (gen_rtx_stack_adjust (PLUS, frame_size));
-+
-+  if (sibcall_p)
-+  {
-+    if (live_regs)
-+      emit_insn (gen_rtx_register_pushpop (UNSPEC_POP_RS, live_regs));
-+  }
-+  else
-+  {
-+    if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
-+        emit_insn (
-+          gen_rtx_register_pushpop (UNSPEC_POP_RS, PC_REGBIT | live_regs));
-+  
-+    if (m6809_current_function_has_type_attr_p ("interrupt"))
-+      emit_jump_insn (gen_return_rti ());
-+    else
-+      emit_jump_insn (gen_return_rts ());
-+  }
-+}
-+
-+#if 0
-+/** Predefine some preprocessor names according to the currently
-+ * selected compiler options */
-+void
-+m6809_cpu_cpp_builtins (void)
-+{
-+	if (TARGET_6309)
-+	{
-+		builtin_define_std ("__M6309__");
-+		builtin_define_std ("__m6309__");
-+	}
-+	else
-+	{
-+		builtin_define_std ("__M6809__");
-+		builtin_define_std ("__m6809__");
-+	}
-+
-+	if (TARGET_BYTE_INT)
-+		builtin_define_std ("__int8__");
-+	else
-+		builtin_define_std ("__int16__");
-+
-+	switch (m6809_abi_version)
-+	{
-+		case M6809_ABI_VERSION_STACK:
-+			builtin_define_std ("__regargs__");
-+			builtin_define_std ("__ABI_STACK__");
-+			break;
-+		case M6809_ABI_VERSION_REGS:
-+			builtin_define_std ("__ABI_REGS__");
-+			break;
-+		case M6809_ABI_VERSION_BX:
-+			builtin_define_std ("__ABI_BX__");
-+			break;
-+		default:
-+			break;
-+	}
-+
-+	if (TARGET_WPC)
-+		builtin_define_std ("__WPC__");
-+
-+	if (TARGET_DRET)
-+		builtin_define_std ("__DRET__");
-+}
-+#endif
-+
-+#define MAX_ASM_ASCII_STRING 48
-+
-+void
-+m6809_output_ascii (FILE *fp, const char *str, unsigned long size)
-+{
-+	unsigned long i;
-+	bool use_ascii = true;
-+
-+	/* If the size is too large, then break this up into multiple
-+	outputs.  The assembler can only output roughly 48 bytes at a
-+	time.  Note that if there are lots of escape sequences in
-+	the string, this may fail. */
-+	if (size > MAX_ASM_ASCII_STRING)
-+	{
-+		m6809_output_ascii (fp, str, MAX_ASM_ASCII_STRING);
-+		m6809_output_ascii (fp, str + MAX_ASM_ASCII_STRING, 
-+			size - MAX_ASM_ASCII_STRING);
-+		return;
-+	}
-+
-+	/* Check for 8-bit codes, which cannot be embedded in an .ascii */
-+	for (i = 0; i < size; i++)
-+	{
-+		int c = str[i] & 0377;
-+		if (c >= 0x80)
-+		{
-+			use_ascii = false;
-+			break;
-+		}
-+	}
-+
-+	if (use_ascii)
-+		fprintf (fp, "\t.ascii \"");
-+
-+	for (i = 0; i < size; i++)
-+	{
-+		int c = str[i] & 0377;
-+
-+		if (use_ascii)
-+		{
-+		/* Just output the plain character if it is printable,
-+		otherwise output the escape code for the character.
-+		The assembler recognizes the same C-style octal escape sequences,
-+		except that it only supports 7-bit codes. */
-+		if (c >= ' ' && c < 0177 && c != '\\' && c != '"')
-+  			putc (c, fp);
-+		else switch (c) 
-+		{
-+			case '\n':
-+#ifndef TARGET_COCO
-+				fputs ("\\n", fp);
-+				break;
-+#endif
-+				/* On the CoCo, we fallthrough and treat '\n' like '\r'. */
-+			case '\r':
-+				fputs ("\\r", fp);
-+				break;
-+			case '\t':
-+				fputs ("\\t", fp);
-+				break;
-+			case '\f':
-+				fputs ("\\f", fp);
-+				break;
-+			case 0:
-+				fputs ("\\0", fp);
-+				break;
-+			default:
-+				fprintf (fp, "\\%03o", c);
-+				break;
-+		}
-+		}
-+		else
-+		{
-+			fprintf (fp, "\t.byte\t0x%02X\n", c);
-+		}
-+	}
-+
-+	if (use_ascii)
-+		fprintf (fp, "\"\n");
-+}
-+
-+
-+void
-+m6809_output_quoted_string (FILE *asm_file, const char *string)
-+{
-+	char c;
-+
-+	if (strlen (string) > MAX_ASM_ASCII_STRING)
-+	{
-+		/* The string length is too large.  We'll have to truncate it.
-+		This is only called from debugging functions, so it's usually
-+		not critical. */
-+
-+		char truncated_string[MAX_ASM_ASCII_STRING+1];
-+
-+		/* Copy as many characters as we can. */
-+		strncpy (truncated_string, string, MAX_ASM_ASCII_STRING);
-+		truncated_string[MAX_ASM_ASCII_STRING] = '\0';
-+		string = truncated_string;
-+	}
-+
-+	/* Copied from toplev.c */
-+
-+	putc ('\"', asm_file);
-+	while ((c = *string++) != 0) {
-+		if (ISPRINT (c)) {
-+			if (c == '\"' || c == '\\')
-+				putc ('\\', asm_file);
-+			putc (c, asm_file);
-+		}
-+      else
-+			fprintf (asm_file, "\\%03o", (unsigned char) c);
-+	}
-+	putc ('\"', asm_file);
-+}
-+
-+
-+/** Output the assembly code for a shift instruction where the
-+ * shift count is not constant. */
-+void
-+m6809_output_shift_insn (int rtx_code, rtx *operands)
-+{
-+	struct shift_opcode *op;
-+
-+	if (GET_CODE (operands[2]) == CONST_INT)
-+		abort ();
-+
-+	if (optimize_size && GET_MODE (operands[0]) == HImode)
-+	{
-+		switch (rtx_code)
-+		{
-+			case ASHIFT:
-+				output_asm_insn ("jsr\t_ashlhi3", operands);
-+				break;
-+			case ASHIFTRT:
-+				output_asm_insn ("jsr\t_ashrhi3", operands);
-+				break;
-+			case LSHIFTRT:
-+				output_asm_insn ("jsr\t_lshrhi3", operands);
-+				break;
-+		}
-+	}
-+	else if (GET_MODE (operands[0]) == HImode)
-+	{
-+		switch (rtx_code)
-+		{
-+			case ASHIFT:
-+				m6809_gen_register_shift (operands, "aslb", "rola");
-+				break;
-+			case ASHIFTRT:
-+				m6809_gen_register_shift (operands, "asra", "rorb");
-+				break;
-+			case LSHIFTRT:
-+				m6809_gen_register_shift (operands, "lsra", "rorb");
-+				break;
-+		}
-+	}
-+	else
-+	{
-+		switch (rtx_code)
-+		{
-+			case ASHIFT:
-+				m6809_gen_register_shift (operands, "aslb", NULL);
-+				break;
-+			case ASHIFTRT:
-+				m6809_gen_register_shift (operands, "asrb", NULL);
-+				break;
-+			case LSHIFTRT:
-+				m6809_gen_register_shift (operands, "lsrb", NULL);
-+				break;
-+		}
-+	}
-+}
-+
-+
-+void
-+m6809_emit_move_insn (rtx dst, rtx src)
-+{
-+	emit_insn (gen_rtx_SET (VOIDmode, dst, src));
-+	if (ACC_A_REG_P (dst))
-+		emit_insn (gen_rtx_USE (VOIDmode, dst));
-+}
-+
-+
-+/** Split a complex shift instruction into multiple CPU
-+ * shift instructions. */
-+void
-+m6809_split_shift (enum rtx_code code, rtx *operands)
-+{
-+	enum machine_mode mode;
-+	int count;
-+
-+	mode = GET_MODE (operands[0]);
-+	count = INTVAL (operands[2]);
-+	
-+	/* Handle a shift count outside the range of 0 .. N-1, where
-+	 * N is the mode size in bits.  We normalize the count, and
-+	 * for negative counts we also invert the direction of the
-+	 * shift. */
-+	if ((count < 0) || (count >= 8 * GET_MODE_SIZE (mode)))
-+	{
-+		if (count < 0)
-+		{
-+			count = -count;
-+			code = (code == ASHIFT) ? ASHIFTRT : ASHIFT;
-+		}
-+		count %= (8 * GET_MODE_SIZE (mode));
-+		m6809_emit_move_insn (operands[0],
-+			gen_rtx_fmt_ee (code, mode, operands[1],
-+				gen_rtx_CONST_INT (VOIDmode, count)));
-+	}
-+
-+	/* Handle shift by zero explicitly as a no-op. */
-+	if (count == 0)
-+	{
-+		emit_insn (gen_nop ());
-+		return;
-+	}
-+
-+	/* Decompose the shift by a constant N > 8 into two
-+	 * shifts, first by 8 and then by N-8.
-+	 * This "speeds up" the process for large shifts that would be
-+	 * handled below, but allows for some optimization.
-+	 * In some cases shift by 8 can be implemented fast.  If an
-+	 * instruction to shift by 8 is defined, it will be used here;
-+	 * otherwise it will be further decomposed as below. */
-+	if (mode == HImode && count > 8)
-+	{
-+		rtx output = operands[0];
-+
-+		m6809_emit_move_insn (operands[0],
-+			gen_rtx_fmt_ee (code, mode, operands[1],
-+				gen_rtx_CONST_INT (VOIDmode, 8)));
-+
-+		/* Unsigned shifts always produce a zero in either the
-+		 * upper or lower half of the output; then, that part
-+		 * does not need to be shifted anymore.  We modify the
-+		 * output and the subsequent instructions to operate in
-+		 * QImode only on the relevant part. */
-+		if (REG_P (output))
-+		{
-+			if (code == ASHIFT)
-+			{
-+				output = gen_rtx_REG (QImode, HARD_A_REGNUM);
-+				mode = QImode;
-+			}
-+			else
-+			{
-+				output = gen_rtx_REG (QImode, HARD_D_REGNUM);
-+				mode = QImode;
-+			}
-+		}
-+
-+		m6809_emit_move_insn (output,
-+			gen_rtx_fmt_ee (code, mode, copy_rtx (output), 
-+				gen_rtx_CONST_INT (VOIDmode, count-8)));
-+		return;
-+	}
-+
-+	/* Rewrite the unsigned shift of an 8-bit register by a large constant N
-+	 * (near to the maximum of 8) as a rotate and mask. */
-+	if (mode == QImode && REG_P (operands[0]) && count >= ((code == ASHIFTRT) ? 7 : 6))
-+	{
-+		unsigned int mask;
-+		unsigned int was_signed = (code == ASHIFTRT);
-+
-+		code = (code == ASHIFT) ? ROTATERT : ROTATE;
-+		if (code == ROTATE)
-+			mask = (count == 6) ? 0x03 : 0x01;
-+		else
-+			mask = (count == 6) ? 0xC0 - 0x100 : 0x80 - 0x100;
-+		count = 9 - count;
-+
-+		do {
-+			m6809_emit_move_insn (operands[0],
-+				gen_rtx_fmt_ee (code, QImode, operands[1], const1_rtx));
-+		} while (--count != 0);
-+
-+		m6809_emit_move_insn (operands[0],
-+			gen_rtx_fmt_ee (AND, QImode, operands[1],
-+				gen_rtx_CONST_INT (VOIDmode, mask)));
-+
-+		if (was_signed)
-+		{
-+			emit_insn (gen_negqi2 (operands[0], copy_rtx (operands[0])));
-+			if (ACC_A_REG_P (operands[0]))
-+				emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
-+		}
-+		return;
-+	}
-+
-+	/* Decompose the shift by any constant N > 1 into a sequence
-+	 * of N shifts.
-+	 * This is done recursively, by creating a shift by 1 and a
-+	 * shift by N-1, as long as N>1. */
-+	if (count > 1)
-+	{
-+		m6809_emit_move_insn (operands[0],
-+			gen_rtx_fmt_ee (code, mode, operands[1], const1_rtx));
-+	
-+		m6809_emit_move_insn (operands[0],
-+			gen_rtx_fmt_ee (code, mode, operands[1], 
-+				gen_rtx_CONST_INT (VOIDmode, count-1)));
-+		return;
-+	}
-+	
-+	/* Decompose the single shift of a 16-bit quantity into two
-+	 * CPU instructions, one for each 8-bit half.
-+	 */
-+	if (mode == HImode && count == 1)
-+	{
-+		rtx first, second;
-+		enum rtx_code rotate_code;
-+
-+		rotate_code = (code == ASHIFT) ? ROTATE : ROTATERT;
-+
-+		/* Split the operand into two 8-bit entities.
-+		 * FIRST is the one that will get shifted via a regular CPU
-+		 * instruction.
-+		 * SECOND is the one that will have the result of the first shift
-+		 * rotated in.
-+		 *
-+		 * We initialize first and second as if we are doing a left shift,
-+		 * then swap the operands if it's a right shift.
-+		 */
-+		if (REG_P (operands[0]))
-+		{
-+			first = gen_rtx_REG (QImode, HARD_D_REGNUM); /* HARD_B_REGNUM? */
-+			second = gen_rtx_REG (QImode, HARD_A_REGNUM);
-+		}
-+		else
-+		{
-+			first = adjust_address (operands[0], QImode, 1);
-+			second = adjust_address (operands[0], QImode, 0);
-+		}
-+
-+		if (rotate_code == ROTATERT)
-+		{
-+			rtx tmp; tmp = first; first = second; second = tmp;
-+		}
-+
-+		/* Decompose into a shift and a rotate instruction. */
-+		m6809_emit_move_insn (first,
-+			gen_rtx_fmt_ee (code, QImode, copy_rtx (first), const1_rtx));
-+		m6809_emit_move_insn (second,
-+			gen_rtx_fmt_ee (rotate_code, QImode, copy_rtx (second), const1_rtx));
-+		return;
-+	}
-+}
-+
-+
-+/** Adjust register usage based on compile-time flags. */
-+void
-+m6809_conditional_register_usage (void)
-+{
-+	unsigned int soft_regno;
-+
-+#ifdef CONFIG_SOFT_REGS_ALWAYS
-+	m6809_soft_regs = CONFIG_SOFT_REGS_ALWAYS;
-+#else
-+	if (!m6809_soft_reg_count)
-+		return;
-+	m6809_soft_regs = atoi (m6809_soft_reg_count);
-+#endif
-+
-+	if (m6809_soft_regs == 0)
-+		return;
-+
-+	if (m6809_soft_regs > NUM_M_REGS)
-+		m6809_soft_regs = NUM_M_REGS;
-+
-+	/* Registers are marked FIXED by default.  Free up if
-+	the user wishes. */
-+	for (soft_regno = 1; soft_regno < m6809_soft_regs; soft_regno++)
-+	{
-+		fixed_regs[SOFT_M0_REGNUM + soft_regno] = 0;
-+
-+		/* Mark the softregs as call-clobbered, so that they need
-+		 * not be saved/restored on function entry/exit. */
-+		call_used_regs[SOFT_M0_REGNUM + soft_regno] = 1;
-+	}
-+}
-+
-+
-+/** Return a RTX representing how to return a value from a function.
-+  VALTYPE gives the type of the value, FUNC identifies the function
-+  itself.
-+
-+  In general, we only care about the width of the result. */
-+rtx
-+m6809_function_value (const tree valtype, const tree func ATTRIBUTE_UNUSED)
-+{
-+   unsigned int regno;
-+	enum machine_mode mode;
-+
-+	/* Get the mode (i.e. width) of the result. */
-+	mode = TYPE_MODE (valtype);
-+
-+	if (lookup_attribute ("boolean", TYPE_ATTRIBUTES (valtype)))
-+      regno = HARD_Z_REGNUM;
-+   else if (mode == QImode || (TARGET_DRET && mode == HImode))
-+      regno = HARD_D_REGNUM;
-+   else
-+      regno = HARD_X_REGNUM;
-+   return gen_rtx_REG (mode, regno);
-+}
-+
-+
-+/** Return 1 if REGNO is possibly needed to return the result
-+of a function, 0 otherwise. */
-+int
-+m6809_function_value_regno_p (unsigned int regno)
-+{
-+	if (regno == HARD_Z_REGNUM)
-+		return 1;
-+	else if ((TARGET_BYTE_INT || TARGET_DRET) && regno == HARD_D_REGNUM)
-+		return 1;
-+	else if (!TARGET_DRET && regno == HARD_X_REGNUM)
-+		return 1;
-+	else
-+		return 0;
-+}
-+
-+
-+#ifdef TRACE_PEEPHOLE
-+int
-+m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage)
-+{
-+	if (stage == PEEP_END)
-+	{
-+		printf ("%s: peephole %d pattern and predicate matched\n",
-+			main_input_filename, peephole_id);
-+		fflush (stdout);
-+	}
-+	else if (stage == PEEP_COND)
-+	{
-+		printf ("%s: peephole %d? at least pattern matched\n",
-+			main_input_filename, peephole_id);
-+		fflush (stdout);
-+	}
-+	return 1;
-+}
-+#else
-+int
-+m6809_match_peephole2 (unsigned int peephole_id ATTRIBUTE_UNUSED,
-+	unsigned int stage ATTRIBUTE_UNUSED)
-+{
-+	return 1;
-+}
-+#endif /* TRACE_PEEPHOLE */
-+
-+
-+/** Return 1 if it is OK to store a value of MODE in REGNO. */
-+int
-+m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
-+{
-+   /* Soft registers, as they are just memory, can really hold
-+   values of any type.  However we restrict them to values of
-+   size HImode or QImode to prevent exhausting them for larger
-+   values.
-+      Word values cannot be placed into the first soft register,
-+   as it is the low byte that is being placed there, which
-+   corrupts the (non-soft) register before it. */
-+   if (M_REGNO_P (regno))
-+   {
-+      switch (GET_MODE_SIZE (mode))
-+      {
-+         case 1:
-+            return 1;
-+         case 2:
-+            return regno != SOFT_M0_REGNUM;
-+         default:
-+            return 0;
-+      }
-+   }
-+
-+   /* VOIDmode can be stored anywhere */
-+   else if (mode == VOIDmode)
-+      return 1;
-+
-+   /* Zero is a reserved register, but problems occur if we don't
-+   say yes here??? */
-+   else if (regno == 0)
-+      return 1;
-+
-+   /* For other registers, return true only if the requested size
-+   exactly matches the hardware size. */
-+   else if ((G_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 2))
-+      return 1;
-+   else if ((BYTE_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 1))
-+      return 1;
-+   else
-+      return 0;
-+}
-+
-+
-+/* exp is the call expression.  DECL is the called function,
-+ * or NULL for an indirect call */
-+bool
-+m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
-+{
-+	tree type, arg;
-+   const char *name;
-+	bool result = 0;
-+	int argcount = 0;
-+	int step = 1;
-+
-+	/* If there is no DECL, it is an indirect call.
-+	 * Never optimize this??? */
-+	if (decl == NULL)
-+		goto done;
-+
-+	/* Never allow an interrupt handler to be optimized this way. */
-+	if (m6809_function_has_type_attr_p (decl, "interrupt"))
-+		goto done;
-+
-+	/* Skip sibcall if the type can't be found for
-+	 * some reason */
-+	step++;
-+	name = IDENTIFIER_POINTER (DECL_NAME (decl));
-+	type = TREE_TYPE (decl);
-+	if (type == NULL)
-+		goto done;
-+
-+	/* Skip sibcall if the target is a far function */
-+	step++;
-+	if (far_function_type_p (type) != NULL)
-+		goto done;
-+
-+	/* Skip sibcall if the called function's arguments are
-+	 * variable */
-+	step++;
-+	if (TYPE_ARG_TYPES (type) == NULL)
-+		goto done;
-+
-+	/* Allow sibcalls in other cases. */
-+	result = 1;
-+done:
-+	/* printf ("%s ok for sibcall? %s, step %d, args %d\n", name, result ? "yes" : "no", step, argcount); */
-+	return result;
-+}
-+
-+
-+/** Emit code for the 'casesi' pattern.
-+ * This pattern is only used in 8-bit mode, and can be disabled
-+ * with -mold-case there as well.  The rationale for this is to
-+ * do a better job than the simpler but well-tested 'tablejump'
-+ * method.
-+ *
-+ * For small jumptables, where the switch expression is an
-+ * 8-bit value, the lookup can be done more efficiently
-+ * using the "B,X" style index mode. */
-+void
-+m6809_do_casesi (rtx index, rtx lower_bound, rtx range,
-+	rtx table_label, rtx default_label)
-+{
-+	enum machine_mode mode;
-+	rtx scaled;
-+	rtx table_in_reg;
-+
-+	/* expr.c has to be patched so that it does not promote
-+	 * the expression to SImode, but rather to HImode.
-+	 * Fail now if that isn't the case. */
-+	if (GET_MODE_SIZE (GET_MODE (index)) > GET_MODE_SIZE (HImode))
-+		error ("try_casesi promotion bug");
-+
-+	/* Determine whether or not we are going to work primarily in
-+	 * QImode or HImode.  This depends on the size of the index
-+	 * into the lookup table.  QImode can only be used when the
-+	 * index is less than 0x40, since it will be doubled but
-+	 * must remain unsigned. */
-+	if ((GET_CODE (range) == CONST_INT) && (INTVAL (range) < 0x40))
-+		mode = QImode;
-+	else
-+		mode = HImode;
-+
-+	/* Convert to QImode if necessary */
-+	if (mode == QImode)
-+	{
-+		index = gen_lowpart_general (mode, index);
-+		lower_bound = gen_lowpart_general (mode, lower_bound);
-+	}
-+
-+	/* Translate from case value to table index by subtraction */
-+	if (lower_bound != const0_rtx)
-+		index = expand_binop (mode, sub_optab, index, lower_bound,
-+			NULL_RTX, 0, OPTAB_LIB_WIDEN);
-+
-+	/* Emit compare-and-jump to test for index out-of-range */
-+	emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
-+		default_label);
-+
-+	/* Put the table address is in a register */
-+	table_in_reg = gen_reg_rtx (Pmode);
-+	emit_move_insn (table_in_reg, gen_rtx_LABEL_REF (Pmode, table_label));
-+
-+	/* Emit table lookup and jump */
-+	if (mode == QImode)
-+	{
-+		/* Scale the index */
-+		scaled = gen_reg_rtx (QImode);
-+		emit_insn (gen_ashlqi3 (scaled, index, const1_rtx));
-+
-+		/* Emit the jump */
-+		emit_jump_insn (gen_tablejump_short_offset (scaled, table_in_reg));
-+	}
-+	else
-+	{
-+		/* Scale the index */
-+		emit_insn (gen_ashlhi3 (index, index, const1_rtx));
-+
-+		/* Emit the jump */
-+		emit_jump_insn (gen_tablejump_long_offset (index, table_in_reg));
-+	}
-+
-+	/* Copied from expr.c */
-+	if (!CASE_VECTOR_PC_RELATIVE && !flag_pic)
-+		emit_barrier ();
-+}
-+
-+
-+/** Output the assembly code for a 32-bit add/subtract. */
-+void
-+m6809_output_addsi3 (int rtx_code, rtx *operands)
-+{
-+	rtx xoperands[8];
-+	rtx dst = operands[0];
-+
-+	/* Prepare the operands by splitting each SImode into two HImodes
-+	that can be operated independently.  The high word of operand 1
-+	is further divided into two QImode components for use with 'adc'
-+	style instructions. */
-+	xoperands[7] = operands[3];
-+
-+	xoperands[0] = adjust_address (dst, HImode, 2);
-+	xoperands[3] = adjust_address (dst, HImode, 0);
-+
-+#if 1
-+	xoperands[2] = adjust_address (operands[1], HImode, 2);
-+	xoperands[6] = adjust_address (operands[1], HImode, 0);
-+
-+	/* Operand 2 may be a MEM or a CONST_INT */
-+	if (GET_CODE (operands[2]) == CONST_INT)
-+	{
-+		xoperands[1] = gen_int_mode (INTVAL (operands[2]) & 0xFFFF, HImode);
-+		xoperands[4] = gen_int_mode ((INTVAL (operands[2]) >> 24) & 0xFF, QImode);
-+		xoperands[5] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFF, QImode);
-+	}
-+	else
-+	{
-+		xoperands[1] = adjust_address (operands[2], HImode, 2);
-+		xoperands[4] = adjust_address (operands[2], QImode, 0);
-+		xoperands[5] = adjust_address (operands[2], QImode, 1);
-+	}
-+
-+#endif
-+
-+#if 0
-+	xoperands[1] = adjust_address (operands[1], HImode, 2);
-+	xoperands[4] = adjust_address (operands[1], QImode, 0);
-+	xoperands[5] = adjust_address (operands[1], QImode, 1);
-+
-+	/* Operand 2 may be a MEM or a CONST_INT */
-+	if (GET_CODE (operands[2]) == CONST_INT)
-+	{
-+		xoperands[2] = gen_int_mode ((INTVAL (operands[2])) & 0xFFFF, HImode);
-+		xoperands[6] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFFFF, HImode);
-+	}
-+	else
-+	{
-+		xoperands[2] = adjust_address (operands[2], HImode, 2);
-+		xoperands[6] = adjust_address (operands[2], HImode, 0);
-+	}
-+#endif
-+
-+	/* Output the assembly code. */
-+	if (rtx_code == PLUS)
-+	{
-+		output_asm_insn ("ld%7\t%2", xoperands);
-+		output_asm_insn ("add%7\t%1", xoperands);
-+		output_asm_insn ("st%7\t%0", xoperands);
-+		output_asm_insn ("ld%7\t%6", xoperands);
-+		output_asm_insn ("adcb\t%5", xoperands);
-+		output_asm_insn ("adca\t%4", xoperands);
-+		output_asm_insn ("st%7\t%3", xoperands);
-+	}
-+	else
-+	{
-+		output_asm_insn ("ld%7\t%2", xoperands);
-+		output_asm_insn ("sub%7\t%1", xoperands);
-+		output_asm_insn ("st%7\t%0", xoperands);
-+		output_asm_insn ("ld%7\t%6", xoperands);
-+		output_asm_insn ("sbcb\t%5", xoperands);
-+		output_asm_insn ("sbca\t%4", xoperands);
-+		output_asm_insn ("st%7\t%3", xoperands);
-+	}
-+}
-+
-+
-+#if 0
-+/** Output the assembly code for a 32-bit shift.
-+Operands 0 and 1 must be the same rtx, forced by a matching
-+constraint.  Operand 2 must be a CONST_INT.  Operand 3 is
-+"d" in case a temporary reg is needed. */
-+void
-+m6809_output_shiftsi3 (int rtx_code, rtx *operands)
-+{
-+	unsigned int count = INTVAL (operands[2]) % 32;
-+	unsigned int size = 4; /* sizeof (SImode) */
-+	int s;
-+	rtx xoperands[4];
-+	int op;
-+	int start, end, step;
-+
-+	/* Initialize */
-+	if (rtx_code == ASHIFT)
-+	{
-+		start = size-1;
-+		end = -1;
-+		step = -1;
-+	}
-+	else
-+	{
-+		start = 0;
-+		end = size;
-+		step = 1;
-+	}
-+
-+	xoperands[2] = operands[2];
-+	xoperands[3] = operands[3];
-+
-+	if (count <= 0)
-+		abort ();
-+	if (rtx_code == ROTATE || rtx_code == ROTATERT)
-+		abort ();
-+
-+	/* Extract bit shifts over 16 bits by HImode moves. */
-+	if (count >= 16)
-+	{
-+	}
-+
-+	/* Extract bit shifts over 8 bits by QImode moves. */
-+	if (count >= 8)
-+	{
-+	}
-+
-+	/* Iterate over the number of bits to be shifted. */
-+	while (count > 0)
-+	{
-+		/* Each bit to be shifted requires 1 proper bit shift
-+		and 3 rotates. */
-+
-+		/* First, do the arithmetic/logical shift.  Left shifts
-+		start from the LSB; right shifts start from the MSB. */
-+		xoperands[0] = adjust_address (operands[0], QImode, start);
-+		switch (rtx_code)
-+		{
-+			case ASHIFT:
-+				output_asm_insn ("asl\t%0", xoperands);
-+				start--;
-+				break;
-+			case ASHIFTRT:
-+				output_asm_insn ("asr\t%0", xoperands);
-+				start++;
-+				break;
-+			case LSHIFTRT:
-+				output_asm_insn ("lsr\t%0", xoperands);
-+				start++;
-+				break;
-+		}
-+
-+		/* Next, rotate the other bytes */
-+		for (s = start; s != end; s += step)
-+		{
-+			xoperands[0] = adjust_address (operands[0], QImode, s);
-+			switch (rtx_code)
-+			{
-+				case ASHIFT:
-+					output_asm_insn ("rol\t%0", xoperands);
-+					break;
-+				case ASHIFTRT:
-+				case LSHIFTRT:
-+					output_asm_insn ("ror\t%0", xoperands);
-+					break;
-+			}
-+		}
-+		count--;
-+	}
-+}
-+#endif
-+
-+int
-+power_of_two_p (unsigned int n)
-+{
-+	return (n & (n-1)) == 0;
-+}
-+
-+
-+int
-+m6809_can_eliminate (int from, int to)
-+{
-+	if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
-+		return !frame_pointer_needed;
-+	return 1;
-+}
-+
-+
-+int
-+m6809_initial_elimination_offset (int from, int to)
-+{
-+	switch (from)
-+	{
-+		case ARG_POINTER_REGNUM:
-+			return get_frame_size () + m6809_get_regs_size (m6809_get_live_regs ());
-+		case FRAME_POINTER_REGNUM:
-+			return get_frame_size ();
-+		default:
-+			gcc_unreachable ();
-+	}
-+}
-+
-+
-+bool
-+m6809_frame_pointer_required (void)
-+{
-+	return false;
-+}
-+
-+
-+/* Defines the target-specific hooks structure. */
-+struct gcc_target targetm = TARGET_INITIALIZER;
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/m6809.h gcc-4.6.1/gcc/config/m6809/m6809.h
---- gcc-4.6.1-orig/gcc/config/m6809/m6809.h	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/m6809.h	2011-09-18 19:47:50.207654849 -0600
-@@ -0,0 +1,1352 @@
-+/* Definitions of target machine for GNU compiler.  MC6809 version.
-+
-+ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
-+ Space Astronomy Laboratory
-+ University of Wisconsin at Madison
-+
-+ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
-+ ( msdoerfe@informatik.uni-erlangen.de )
-+ also added #pragma interrupt (inspired by gcc-6811)
-+
-+ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
-+ (ebotcazou@multimania.com)
-+
-+ minor changes to adapt it to egcs-1.1.2 by Eric Botcazou
-+ (ebotcazou@multimania.com)
-+
-+ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
-+ (ebotcazou@multimania.com)
-+
-+ changes for gcc-3.1.1 by ???
-+
-+ further changes for gcc-3.1.1 and beyond by Brian Dominy
-+ (brian@oddchange.com)
-+
-+ even more changes for gcc-4.6.1 by William Astle (lost@l-w.ca)
-+
-+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/>.  */
-+
-+
-+/* Helper macros for creating strings with macros */
-+#define C_STRING(x) C_STR(x)
-+#define C_STR(x) #x
-+
-+/* Certain parts of GCC include host-side includes, which is bad.
-+ * Some things that get pulled in need to be undone.
-+ */
-+#undef HAVE_GAS_HIDDEN
-+
-+/* Names to predefine in the preprocessor for this target machine.  */
-+/*#define TARGET_CPU_CPP_BUILTINS() m6809_cpu_cpp_builtins () */
-+#define TARGET_CPU_CPP_BUILTINS() do \
-+	{ \
-+		if (TARGET_6309) \
-+		{ \
-+			builtin_define_std ("__M6309__"); \
-+			builtin_define_std ("__m6309__"); \
-+		} \
-+		else \
-+		{ \
-+			builtin_define_std ("__M6809__"); \
-+			builtin_define_std ("__m6809__"); \
-+		} \
-+ \
-+		if (TARGET_BYTE_INT) \
-+			builtin_define_std ("__int8__"); \
-+		else \
-+			builtin_define_std ("__int16__"); \
-+ \
-+		switch (m6809_abi_version) \
-+		{ \
-+			case M6809_ABI_VERSION_STACK: \
-+				builtin_define_std ("__regargs__"); \
-+				builtin_define_std ("__ABI_STACK__"); \
-+				break; \
-+			case M6809_ABI_VERSION_REGS: \
-+				builtin_define_std ("__ABI_REGS__"); \
-+				break; \
-+			case M6809_ABI_VERSION_BX: \
-+				builtin_define_std ("__ABI_BX__"); \
-+				break; \
-+			default: \
-+				break; \
-+		} \
-+ \
-+		if (TARGET_WPC) \
-+			builtin_define_std ("__WPC__"); \
-+ \
-+		if (TARGET_DRET) \
-+			builtin_define_std ("__DRET__"); \
-+	} while (0)
-+
-+/* As an embedded target, we have no libc.  */
-+#ifndef inhibit_libc
-+#define inhibit_libc
-+#endif
-+
-+/* Print subsidiary information on the compiler version in use.  */
-+#define TARGET_VERSION fprintf (stderr, " (MC6809)");
-+
-+/* Run-time compilation parameters selecting different hardware subsets.  */
-+/*extern int target_flags; */
-+extern short *reg_renumber;	/* def in local_alloc.c */
-+
-+/* Runtime current values of section names */
-+extern int section_changed;
-+extern char code_section_op[], data_section_op[], bss_section_op[];
-+
-+#define WARNING_OPT 0,
-+/*extern const char *m6809_abi_version_ptr; */
-+extern unsigned int m6809_soft_regs;
-+extern unsigned int m6809_abi_version;
-+
-+/* ABI versions */
-+
-+#define M6809_ABI_VERSION_STACK 0
-+#define M6809_ABI_VERSION_REGS 1
-+#define M6809_ABI_VERSION_BX 2
-+#define M6809_ABI_VERSION_LATEST  (M6809_ABI_VERSION_BX)
-+
-+/* Allow $ in identifiers */
-+#define DOLLARS_IN_IDENTIFIERS 1
-+
-+/*--------------------------------------------------------------
-+	Target machine storage layout
-+--------------------------------------------------------------*/
-+
-+/* Define this if most significant bit is lowest numbered
-+   in instructions that operate on numbered bit-fields.  */
-+#define BITS_BIG_ENDIAN 0
-+
-+/* Define to 1 if most significant byte of a word is the lowest numbered. */
-+#define BYTES_BIG_ENDIAN 1
-+
-+/* Define to 1 if most significant word of a multiword value is the lowest numbered. */
-+#define WORDS_BIG_ENDIAN 1
-+
-+/* Number of bits in an addressible storage unit */
-+#define BITS_PER_UNIT 8
-+
-+/* Width in bits of a "word", or the contents of a machine register.
-+ * Although the 6809 has a few byte registers, define this to 16-bits
-+ * since this is the natural size of most registers. */
-+#define BITS_PER_WORD 16
-+
-+/* Width of a word, in units (bytes).  */
-+#define UNITS_PER_WORD (BITS_PER_WORD/8)
-+
-+/* Width in bits of a pointer.  See also the macro `Pmode' defined below.  */
-+#define POINTER_SIZE 16
-+
-+/* Allocation boundary (bits) for storing pointers in memory.  */
-+#define POINTER_BOUNDARY 8
-+
-+/* Allocation boundary (bits) for storing arguments in argument list.  */
-+/* PARM_BOUNDARY is divided by BITS_PER_WORD in expr.c -- tej */
-+#define PARM_BOUNDARY 8
-+
-+/* Boundary (bits) on which stack pointer should be aligned.  */
-+#define STACK_BOUNDARY 8
-+
-+/* Allocation boundary (bits) for the code of a function.  */
-+#define FUNCTION_BOUNDARY 8
-+
-+/* Alignment of field after `int : 0' in a structure.  */
-+#define EMPTY_FIELD_BOUNDARY 8
-+
-+/* Every structure's size must be a multiple of this.  */
-+#define STRUCTURE_SIZE_BOUNDARY 8
-+
-+/* Largest mode size to use when putting an object, including
-+ * a structure, into a register.  By limiting this to 16, no
-+ * 32-bit objects will ever be allocated to a pair of hard
-+ * registers.  This is a good thing, since there aren't that
-+ * many of them.  32-bit objects are only needed for floats
-+ * and "long long"s.  Larger values have been tried and did not
-+ * work. */
-+#define MAX_FIXED_MODE_SIZE 16
-+
-+/* No data type wants to be aligned rounder than this.  */
-+#define BIGGEST_ALIGNMENT 8
-+
-+/* Define this if move instructions will actually fail to work
-+   when given unaligned data.  */
-+#define STRICT_ALIGNMENT 0
-+
-+/*--------------------------------------------------------------
-+	 Standard register usage.
-+--------------------------------------------------------------*/
-+
-+/* Register values as bitmasks.
-+ * TODO : merge D_REGBIT and B_REGBIT, and treat this as the same
-+ * register. */
-+#define RSVD1_REGBIT    (1 << HARD_RSVD1_REGNUM)
-+#define D_REGBIT			(1 << HARD_D_REGNUM)
-+#define X_REGBIT			(1 << HARD_X_REGNUM)
-+#define Y_REGBIT			(1 << HARD_Y_REGNUM)
-+#define U_REGBIT			(1 << HARD_U_REGNUM)
-+#define S_REGBIT			(1 << HARD_S_REGNUM)
-+#define PC_REGBIT			(1 << HARD_PC_REGNUM)
-+#define Z_REGBIT        (1 << HARD_Z_REGNUM)
-+#define A_REGBIT			(1 << HARD_A_REGNUM)
-+#define B_REGBIT			(1 << HARD_B_REGNUM)
-+#define CC_REGBIT			(1 << HARD_CC_REGNUM)
-+#define DP_REGBIT			(1 << HARD_DP_REGNUM)
-+#define SOFT_FP_REGBIT  (1 << SOFT_FP_REGNUM)
-+#define SOFT_AP_REGBIT  (1 << SOFT_AP_REGNUM)
-+#define M_REGBIT(n)		(1 << (SOFT_M0_REGNUM + n))
-+
-+/* Macros for dealing with set of registers.
-+ * A register set is just a bitwise-OR of all the register
-+ * bitmask values. */
-+
-+/* Which registers can hold 8-bits */
-+#define BYTE_REGSET \
-+	(Z_REGBIT | A_REGBIT | D_REGBIT | CC_REGBIT | DP_REGBIT | SOFT_M_REGBITS)
-+
-+/* Which registers can hold 16-bits.
-+ * Note: D_REGBIT is defined as both an 8-bit and 16-bit register */
-+#define WORD_REGSET \
-+	(D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT | SOFT_FP_REGBIT | SOFT_AP_REGBIT | RSVD1_REGBIT)
-+
-+/* Returns nonzero if a given REGNO is in the REGSET. */
-+#define REGSET_CONTAINS_P(regno, regset)  (((1 << (regno)) & (regset)) != 0)
-+
-+/* Defines related to the number of soft registers supported.
-+ * The actual number used may be less depending on -msoft-reg-count.
-+ * If you change one of these, you should change them all. */
-+#define NUM_M_REGS 8
-+#define M_REGS_FIXED 1, 1, 1, 1, 1, 1, 1, 1
-+#define M_REGS_CALL_USED 1, 1, 1, 1, 1, 1, 1, 1
-+#define HARD_M_REGNUMS \
-+   SOFT_M0_REGNUM+0, SOFT_M0_REGNUM+1, SOFT_M0_REGNUM+2, SOFT_M0_REGNUM+3, \
-+   SOFT_M0_REGNUM+4, SOFT_M0_REGNUM+5, SOFT_M0_REGNUM+6, SOFT_M0_REGNUM+7
-+
-+#define SOFT_M_REGBITS  (((1UL << NUM_M_REGS) - 1) << (SOFT_M0_REGNUM))
-+
-+/* Number of actual hardware registers.
-+   The hardware registers are assigned numbers for the compiler
-+   from 0 to just below FIRST_PSEUDO_REGISTER.
-+   All registers that the compiler knows about must be given numbers,
-+   even those that are not normally considered general registers.
-+   Make sure the constant below matches the value of SOFT_M0_REGNUM;
-+   for some reason, GCC won't compile if that name is used here directly. */
-+#ifdef SOFT_M0_REGNUM
-+#if (SOFT_M0_REGNUM != 14)
-+#error "bad register numbering"
-+#endif
-+#endif
-+#define FIRST_PSEUDO_REGISTER (14 + NUM_M_REGS)
-+
-+/* 1 for registers that have pervasive standard uses
-+   and are not available for the register allocator.
-+   The psuedoregisters (M_REGS) are declared fixed here, but
-+   will be unfixed if -msoft-reg-count is seen later.  */
-+#define FIXED_REGISTERS \
-+    {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, M_REGS_FIXED, }
-+  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
-+
-+/* 1 for registers not available across function calls.
-+   These must include the FIXED_REGISTERS and also any
-+   registers that can be used without being saved.
-+   The latter must include the registers where values are returned
-+   and the register where structure-value addresses are passed.
-+   Aside from that, you can include as many other registers as you like.  */
-+#define CALL_USED_REGISTERS \
-+    {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, M_REGS_CALL_USED, }
-+  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
-+
-+/* Return number of consecutive hard regs needed starting at reg REGNO
-+   to hold something of mode MODE.
-+	For the 6809, we distinguish between word-length and byte-length
-+	registers. */
-+#define HARD_REGNO_NREGS(REGNO, MODE) \
-+   (REGSET_CONTAINS_P (REGNO, WORD_REGSET) ? \
-+		((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : \
-+      (GET_MODE_SIZE (MODE)))
-+
-+
-+/* Value is 1 if hard register REGNO can hold a value
-+of machine-mode MODE. */
-+#define HARD_REGNO_MODE_OK(REGNO, MODE) m6809_hard_regno_mode_ok (REGNO, MODE)
-+
-+/* Value is 1 if it is a good idea to tie two pseudo registers
-+   when one has mode MODE1 and one has mode MODE2.
-+   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
-+   for any hard reg, then this must be 0 for correct output.  */
-+#define MODES_TIEABLE_P(MODE1, MODE2) 0
-+
-+/* Specify the registers used for certain standard purposes.
-+   The values of these macros are register numbers.  */
-+
-+/* program counter if referenced as a register */
-+#define PC_REGNUM HARD_PC_REGNUM
-+
-+/* Register to use for pushing function arguments.  */
-+#define STACK_POINTER_REGNUM HARD_S_REGNUM
-+
-+/* Base register for access to local variables of the function.
-+ * Before reload, FRAME_POINTER_REGNUM will be used.  Later,
-+ * the elimination pass will convert these to STACK_POINTER_REGNUM
-+ * if possible, or else HARD_FRAME_POINTER_REGNUM.  The idea is to
-+ * avoid tying up a hard register (U) for the frame pointer if
-+ * it can be eliminated entirely, making it available for use as
-+ * a general register. */
-+#define FRAME_POINTER_REGNUM       SOFT_FP_REGNUM
-+#define HARD_FRAME_POINTER_REGNUM  HARD_U_REGNUM
-+
-+/* Define a table of possible eliminations.
-+ * The idea is to try to avoid using hard registers for the argument
-+ * and frame pointers if they can be derived from the stack pointer
-+ * instead, which already has a hard register reserved for it.
-+ *
-+ * The order of entries in this table will try to convert
-+ * ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM into stack pointer
-+ * references first, but if that fails, they will be converted to use
-+ * HARD_FRAME_POINTER_REGNUM.
-+ */
-+#define ELIMINABLE_REGS \
-+{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
-+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
-+ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
-+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
-+
-+/* #define CAN_ELIMINATE(FROM, TO) m6809_can_eliminate (FROM, TO) */
-+
-+/* Define how to offset the frame or argument pointer to turn it
-+ * into a stack pointer reference.  This is based on the way that
-+ * the frame is constructed in the function prologue. */
-+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-+	(OFFSET) = m6809_initial_elimination_offset (FROM, TO)
-+
-+/* Base register for access to arguments of the function.
-+ * This is only used prior to reload; no instructions will ever
-+ * be output referring to this register. */
-+#define ARG_POINTER_REGNUM SOFT_AP_REGNUM
-+
-+/* Register in which static-chain is passed to a function.  */
-+#define STATIC_CHAIN_REGNUM HARD_Y_REGNUM
-+
-+/* #define CONDITIONAL_REGISTER_USAGE (m6809_conditional_register_usage ()) */
-+
-+/* Order in which hard registers are allocated to pseudos.
-+ *
-+ * Since the D register is the only valid reg for 8-bit values
-+ * now, avoid using it for 16-bit values by putting it after all
-+ * other 16-bits.
-+ *
-+ * Prefer X first since the first 16-bit function argument goes
-+ * there.  We may be able to pass in to a subroutine without
-+ * a copy.
-+ *
-+ * Prefer U over Y since instructions using Y take one extra
-+ * byte, and thus one extra cycle to execute.
-+ */
-+#define REG_ALLOC_ORDER \
-+   {  HARD_X_REGNUM, HARD_U_REGNUM, HARD_Y_REGNUM, HARD_D_REGNUM, \
-+	   HARD_M_REGNUMS, HARD_S_REGNUM, HARD_PC_REGNUM, \
-+		HARD_B_REGNUM, HARD_A_REGNUM, HARD_CC_REGNUM, \
-+		HARD_DP_REGNUM, SOFT_FP_REGNUM, SOFT_AP_REGNUM, \
-+		6, HARD_Z_REGNUM }
-+
-+/*--------------------------------------------------------------
-+	classes of registers
-+--------------------------------------------------------------*/
-+
-+/* Define the classes of registers for register constraints in the
-+   machine description.  Also define ranges of constants.
-+
-+   One of the classes must always be named ALL_REGS and include all hard regs.
-+   If there is more than one class, another class must be named NO_REGS
-+   and contain no registers.
-+
-+   The name GENERAL_REGS must be the name of a class (or an alias for
-+   another name such as ALL_REGS).  This is the class of registers
-+   that is allowed by "g" or "r" in a register constraint.
-+   Also, registers outside this class are allocated only when
-+   instructions express preferences for them.
-+
-+   The classes must be numbered in nondecreasing order; that is,
-+   a larger-numbered class must never be contained completely
-+   in a smaller-numbered class.
-+
-+   For any two classes, it is very desirable that there be another
-+   class that represents their union.  */
-+   
-+enum reg_class {
-+    NO_REGS,    /* The trivial class with no registers in it */
-+    D_REGS,     /* 16-bit (word (HI)) data (D) */
-+    ACC_A_REGS, /* The A register */
-+    ACC_B_REGS, /* The B register */
-+	 X_REGS,     /* The X register */
-+	 Z_REGS,     /* The Z (zero-bit) register */
-+    Q_REGS,     /* 8-bit (byte (QI)) data (A,B) */
-+    M_REGS,     /* 8-bit (byte (QI)) soft registers */
-+	 CC_REGS,    /* 8-bit condition code register */
-+    I_REGS,     /* An index register (A,B,D) */
-+    T_REGS,     /* 16-bit addresses, not including stack or PC (X,Y,U) */
-+    A_REGS,     /* 16-bit addresses (X,Y,U,S,PC) */
-+	 S_REGS,     /* 16-bit soft registers (FP, AP) */
-+	 P_REGS,     /* 16-bit pushable registers (D,X,Y,U); omit PC and S */
-+    G_REGS,     /* 16-bit data and address (D,X,Y,U,S,PC) */
-+    ALL_REGS,   /* All registers */
-+    LIM_REG_CLASSES
-+};
-+
-+#define N_REG_CLASSES (int) LIM_REG_CLASSES
-+
-+/* Since GENERAL_REGS is a smaller class than ALL_REGS,
-+   it is not an alias to ALL_REGS, but to G_REGS. */
-+#define GENERAL_REGS G_REGS
-+
-+/* Give names of register classes as strings for dump file.   */
-+#define REG_CLASS_NAMES \
-+ {  "NO_REGS", "D_REGS", "ACC_A_REGS", "ACC_B_REGS", "X_REGS", "Z_REGS", "Q_REGS", "M_REGS", \
-+	 "CC_REGS", "I_REGS", "T_REGS", "A_REGS", "S_REGS", "P_REGS", "G_REGS", \
-+	 "ALL_REGS" }
-+
-+/* Define which registers fit in which classes.
-+   This is an initializer for a vector of HARD_REG_SET
-+   of length N_REG_CLASSES.  */
-+
-+#define D_REGSET	(D_REGBIT)
-+#define ACC_A_REGSET (A_REGBIT)
-+#define ACC_B_REGSET (D_REGBIT)
-+#define X_REGSET (X_REGBIT)
-+#define Z_REGSET (Z_REGBIT)
-+#define Q_REGSET (D_REGBIT | A_REGBIT)
-+#define M_REGSET (SOFT_M_REGBITS)
-+#define CC_REGSET (CC_REGBIT)
-+#define I_REGSET (A_REGBIT | B_REGBIT | D_REGBIT)
-+#define T_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT)
-+#define A_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT)
-+#define S_REGSET (SOFT_FP_REGBIT | SOFT_AP_REGBIT)
-+#define P_REGSET (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT)
-+#define G_REGSET \
-+   (D_REGSET | Q_REGSET | I_REGSET | A_REGSET | M_REGSET | S_REGSET)
-+#define ALL_REGSET (G_REGSET)
-+
-+#define REG_CLASS_CONTENTS { \
-+	{0}, \
-+	{D_REGSET}, \
-+   {ACC_A_REGSET}, \
-+   {ACC_B_REGSET}, \
-+   {X_REGSET}, \
-+   {Z_REGSET}, \
-+	{Q_REGSET}, \
-+	{M_REGSET}, \
-+   {CC_REGSET}, \
-+	{I_REGSET}, \
-+	{T_REGSET}, \
-+	{A_REGSET}, \
-+	{S_REGSET}, \
-+	{P_REGSET}, \
-+	{G_REGSET}, \
-+	{ALL_REGSET}, \
-+}
-+
-+/* The same information, inverted.
-+ * This is defined to use the REG_CLASS_CONTENTS defines above, so that
-+ * these two sets of definitions are always consistent. */
-+
-+#define REGNO_REG_CLASS(REGNO) \
-+  (D_REGNO_P (REGNO) ? D_REGS : \
-+  (Z_REGNO_P (REGNO) ? Z_REGS : \
-+  (ACC_A_REGNO_P (REGNO) ? ACC_A_REGS : \
-+  (ACC_B_REGNO_P (REGNO) ? ACC_B_REGS : \
-+  (X_REGNO_P (REGNO) ? X_REGS : \
-+  (Q_REGNO_P (REGNO) ? Q_REGS : \
-+  (M_REGNO_P (REGNO) ? M_REGS : \
-+  (CC_REGNO_P (REGNO) ? CC_REGS : \
-+  (I_REGNO_P (REGNO) ? I_REGS : \
-+  (T_REGNO_P (REGNO) ? T_REGS : \
-+  (A_REGNO_P (REGNO) ? A_REGS : \
-+  (S_REGNO_P (REGNO) ? S_REGS : \
-+  (P_REGNO_P (REGNO) ? P_REGS : \
-+  (G_REGNO_P (REGNO) ? G_REGS : ALL_REGS))))))))))))))
-+
-+#define D_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, D_REGSET))
-+#define ACC_A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_A_REGSET))
-+#define ACC_B_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_B_REGSET))
-+#define X_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, X_REGSET))
-+#define Z_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Z_REGSET))
-+#define Q_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Q_REGSET))
-+#define M_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, M_REGSET))
-+#define CC_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, CC_REGSET))
-+#define I_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, I_REGSET))
-+#define T_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, T_REGSET))
-+#define A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, A_REGSET))
-+#define S_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, S_REGSET))
-+#define P_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, P_REGSET))
-+#define G_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, G_REGSET))
-+
-+/* Macros that test an rtx 'X' to see if it's in a particular
-+ * register class.  'X' need not be a REG necessarily. */
-+
-+#define D_REG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
-+#define ACC_A_REG_P(X) (REG_P (X) && ACC_A_REGNO_P (REGNO (X)))
-+#define ACC_B_REG_P(X) (REG_P (X) && ACC_B_REGNO_P (REGNO (X)))
-+#define X_REG_P(X) (REG_P (X) && X_REGNO_P (REGNO (X)))
-+#define Z_REG_P(X) (REG_P (X) && Z_REGNO_P (REGNO (X)))
-+#define I_REG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
-+#define T_REG_P(X) (REG_P (X) && T_REGNO_P (REGNO (X)))
-+#define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
-+#define S_REG_P(X) (REG_P (X) && S_REGNO_P (REGNO (X)))
-+#define P_REG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
-+#define Q_REG_P(X) (REG_P (X) && Q_REGNO_P (REGNO (X)))
-+#define M_REG_P(X) (REG_P (X) && M_REGNO_P (REGNO (X)))
-+#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
-+
-+/* Redefine this in terms of BYTE_REGSET */
-+#define BYTE_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, BYTE_REGSET))
-+
-+/* The class value for index registers, and the one for base regs.  */
-+#define INDEX_REG_CLASS I_REGS
-+#define BASE_REG_CLASS A_REGS
-+
-+/* Get reg_class from a letter in the machine description.  */
-+#define REG_CLASS_FROM_LETTER(C) \
-+  (((C) == 'a' ? A_REGS : \
-+   ((C) == 'd' ? D_REGS : \
-+	((C) == 'x' ? I_REGS : \
-+	((C) == 't' ? M_REGS : \
-+	((C) == 'c' ? CC_REGS : \
-+	((C) == 'A' ? ACC_A_REGS : \
-+	((C) == 'B' ? ACC_B_REGS : \
-+	((C) == 'v' ? X_REGS : \
-+	((C) == 'u' ? S_REGS : \
-+	((C) == 'U' ? P_REGS : \
-+	((C) == 'T' ? T_REGS : \
-+	((C) == 'z' ? Z_REGS : \
-+   ((C) == 'q' ? Q_REGS : NO_REGS))))))))))))))
-+
-+/*--------------------------------------------------------------
-+   The letters I through O in a register constraint string
-+   can be used to stand for particular ranges of immediate operands.
-+   This macro defines what the ranges are.
-+   C is the letter, and VALUE is a constant value.
-+   Return 1 if VALUE is in the range specified by C.
-+
-+   For the 6809, J, K, L are used for indexed addressing.
-+   `I' is used for the constant 1.
-+   `J' is used for the 5-bit offsets.
-+   `K' is used for the 8-bit offsets.
-+   `L' is used for the range of signed numbers that fit in 16 bits.
-+   `M' is used for the exact value '8'.
-+   `N' is used for the constant -1.
-+   `O' is used for the constant 0.
-+--------------------------------------------------------------*/
-+
-+#define CONST_OK_FOR_LETTER_P(VALUE, C) \
-+  ((C) == 'I' ? ((VALUE) == 1) : \
-+   (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
-+   (C) == 'K' ? ((VALUE) >= -128 && (VALUE) <= 127) : \
-+   (C) == 'L' ? ((VALUE) >= -32768 && (VALUE) <= 32767) : \
-+   (C) == 'M' ? ((VALUE) == 8) : \
-+   (C) == 'N' ? ((VALUE) == -1) : \
-+   (C) == 'O' ? ((VALUE) == 0) : 0)
-+
-+/* Similar, but for floating constants, and defining letters G and H.
-+   No floating-point constants are valid on MC6809.  */
-+#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
-+   ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
-+     && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
-+
-+/* Given an rtx X being reloaded into a reg required to be
-+   in class CLASS, return the class of reg to actually use.
-+   In general this is just CLASS; but on some machines
-+   in some cases it is preferable to use a more restrictive class.  */
-+#define PREFERRED_RELOAD_CLASS(X,CLASS) m6809_preferred_reload_class(X,CLASS)
-+
-+#define SMALL_REGISTER_CLASSES  1
-+
-+/* Return the maximum number of consecutive registers
-+   needed to represent mode MODE in a register of class CLASS.  */
-+#define CLASS_MAX_NREGS(CLASS, MODE) \
-+    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
-+
-+/*--------------------------------------------------------------
-+	Stack layout; function entry, exit and calling.
-+--------------------------------------------------------------*/
-+
-+/* Define this if pushing a word on the stack
-+   makes the stack pointer a smaller address.  */
-+#define STACK_GROWS_DOWNWARD
-+
-+
-+/* Define this if the nominal address of the stack frame
-+   is at the high-address end of the local variables;
-+   that is, each additional local variable allocated
-+   goes at a more negative offset in the frame.  */
-+#define FRAME_GROWS_DOWNWARD 1
-+
-+
-+/* Offset within stack frame to start allocating local variables at.
-+   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
-+   first local allocated.  Otherwise, it is the offset to the BEGINNING
-+   of the first local allocated.  */
-+#define STARTING_FRAME_OFFSET 0
-+
-+
-+/* Always push stack arguments for now.  Accumulation is not yet working. */
-+#define PUSH_ROUNDING(BYTES) (BYTES)
-+
-+
-+/* Offset of first parameter from the argument pointer register value.
-+ * ARG_POINTER_REGNUM is defined to point to the return address pushed
-+ * onto the stack, so we must offset by 2 bytes to get to the arguments. */
-+#define FIRST_PARM_OFFSET(FNDECL) 2
-+
-+/* Value is 1 if returning from a function call automatically
-+   pops the arguments described by the number-of-args field in the call.
-+   FUNTYPE is the data type of the function (as a tree),
-+   or for a library call it is an identifier node for the subroutine name. */
-+/* #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 */
-+
-+/* Define how to find the value returned by a function.
-+   VALTYPE is the data type of the value (as a tree).
-+   If the precise function being called is known, FUNC is its FUNCTION_DECL;
-+   otherwise, FUNC is 0.  */
-+#define FUNCTION_VALUE(VALTYPE, FUNC) m6809_function_value (VALTYPE, FUNC)
-+
-+/* Define how to find the value returned by a library function
-+   assuming the value has mode MODE.  */
-+
-+/* All return values are in the X-register. */
-+#define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, HARD_X_REGNUM)
-+
-+/* Define this if using the nonreentrant convention for returning
-+   structure and union values.  No; it is inefficient and buggy. */
-+#undef PCC_STATIC_STRUCT_RETURN
-+
-+/* 1 if N is a possible register number for a function value. */
-+#define FUNCTION_VALUE_REGNO_P(N) m6809_function_value_regno_p (N)
-+
-+/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
-+   more than one register.  */
-+#define NEEDS_UNTYPED_CALL 1
-+
-+/* 1 if N is a possible register number for function argument passing. */
-+#define FUNCTION_ARG_REGNO_P(N) \
-+	((m6809_abi_version != M6809_ABI_VERSION_STACK) ? \
-+   	(((N) == HARD_D_REGNUM) || ((N) == HARD_X_REGNUM)) : \
-+		0)
-+
-+/*--------------------------------------------------------------
-+	Argument Lists
-+--------------------------------------------------------------*/
-+
-+/* Cumulative arguments are tracked in a single integer, 
-+ * which is the number of bytes of arguments scanned so far,
-+ * plus which registers have already been used.  The register
-+ * info is kept in some of the upper bits */
-+#define CUMULATIVE_ARGS unsigned int
-+
-+#define CUM_STACK_ONLY 0x80000000
-+#define CUM_X_MASK     0x40000000
-+#define CUM_B_MASK     0x20000000
-+#define CUM_STACK_INVALID 0x10000000
-+#define CUM_STACK_MASK 0xFFFFFFF
-+
-+#define CUM_ADVANCE_8BIT(cum) \
-+	(((cum) & CUM_B_MASK) ? (cum)++ : ((cum) |= CUM_B_MASK))
-+
-+#define CUM_ADVANCE_16BIT(cum) \
-+	(((cum) & CUM_X_MASK) ? (cum) += 2 : ((cum) |= CUM_X_MASK))
-+
-+/* 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.
-+	N_NAMED was added in gcc 3.4 and is not used currently. */
-+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED) \
-+	((CUM) = m6809_init_cumulative_args (CUM, FNTYPE, LIBNAME))
-+
-+#define FUNCTION_ARG_SIZE(MODE, TYPE)	\
-+  ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)	\
-+   : (unsigned) int_size_in_bytes (TYPE))
-+
-+/* 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.)  */
-+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-+	 (((MODE == QImode) && !((CUM) & CUM_STACK_ONLY)) ? \
-+		CUM_ADVANCE_8BIT (CUM) : \
-+	  ((MODE == HImode) && !((CUM) & CUM_STACK_ONLY)) ? \
-+		CUM_ADVANCE_16BIT (CUM) : \
-+	  ((CUM) = ((CUM) + (TYPE ? int_size_in_bytes (TYPE) : 2))))
-+
-+/* Define where to put the arguments to a function.
-+   Value is zero to push the argument on the stack,
-+   or a hard register rtx in which to store the argument.
-+	This macro is used _before_ FUNCTION_ARG_ADVANCE.
-+
-+	For the 6809, the first 8-bit function argument can be placed into B,
-+	and the first 16-bit arg can go into X.  All other arguments
-+	will be pushed onto the stack.
-+
-+	Command-line options can adjust this behavior somewhat.
-+ */
-+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
-+	((MODE == VOIDmode) ? NULL_RTX : \
-+	((MODE == BLKmode) || (GET_MODE_SIZE (MODE) > 2)) ? NULL_RTX : \
-+	((MODE == QImode) && !((CUM) & (CUM_STACK_ONLY | CUM_B_MASK))) ? \
-+		gen_rtx_REG (QImode, HARD_D_REGNUM) : \
-+	((MODE == HImode) && !((CUM) & (CUM_STACK_ONLY | CUM_X_MASK))) ?  \
-+		gen_rtx_REG (HImode, HARD_X_REGNUM) : m6809_function_arg_on_stack (&CUM))
-+
-+/* Output assembler code to FILE to increment profiler label # LABELNO
-+   for profiling a function entry.  */
-+#define FUNCTION_PROFILER(FILE, LABELNO) \
-+   fprintf (FILE, "\tldd\t#LP%u\n\tjsr\tmcount\n", (LABELNO));
-+
-+/* Stack pointer must be correct on function exit */
-+#define EXIT_IGNORE_STACK 0
-+
-+/*****************************************************************************
-+**
-+** Trampolines for Nested Functions
-+**
-+*****************************************************************************/
-+
-+/* Length in units of the trampoline for entering a nested function.  */
-+#define TRAMPOLINE_SIZE 7
-+
-+/*--------------------------------------------------------------
-+	Addressing modes,
-+	and classification of registers for them.
-+--------------------------------------------------------------*/
-+
-+/* 6809 has postincrement and predecrement addressing modes */
-+#define HAVE_POST_INCREMENT  1
-+#define HAVE_PRE_DECREMENT  1
-+
-+/* Whether or not to use index registers is configurable.
-+ * Experiments show that things work better when this is off, so
-+ * that's the way it is for now. */
-+#undef USE_INDEX_REGISTERS
-+
-+
-+/* Macros to check register numbers against specific register classes.  */
-+#define REG_VALID_FOR_BASE_P(REGNO) \
-+	(((REGNO) < FIRST_PSEUDO_REGISTER) && A_REGNO_P (REGNO))
-+
-+/* MC6809 index registers do not allow scaling, */
-+/* but there is "accumulator-offset" mode. */
-+#ifdef USE_INDEX_REGISTERS
-+#define REG_VALID_FOR_INDEX_P(REGNO) \
-+	(((REGNO) < FIRST_PSEUDO_REGISTER) && I_REGNO_P (REGNO))
-+#else
-+#define REG_VALID_FOR_INDEX_P(REGNO) 0
-+#endif
-+
-+/* Internal macro, the nonstrict definition for REGNO_OK_FOR_BASE_P */
-+#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO) \
-+   ((REGNO) >= FIRST_PSEUDO_REGISTER \
-+	|| REG_VALID_FOR_BASE_P (REGNO) \
-+	|| (REGNO) == FRAME_POINTER_REGNUM \
-+	|| (REGNO) == HARD_FRAME_POINTER_REGNUM \
-+	|| (REGNO) == ARG_POINTER_REGNUM \
-+	|| (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
-+
-+/* Internal macro, the nonstrict definition for REGNO_OK_FOR_INDEX_P */
-+#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
-+   ((REGNO) >= FIRST_PSEUDO_REGISTER \
-+	|| REG_VALID_FOR_INDEX_P (REGNO) \
-+	|| (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
-+
-+
-+/* Internal macro, the strict definition for REGNO_OK_FOR_BASE_P */
-+#define REGNO_OK_FOR_BASE_STRICT_P(REGNO) \
-+	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_BASE_P (REGNO) \
-+	: (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
-+
-+
-+/* Internal macro, the strict definition for REGNO_OK_FOR_INDEX_P */
-+#define REGNO_OK_FOR_INDEX_STRICT_P(REGNO) \
-+	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_INDEX_P (REGNO) \
-+	: (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
-+
-+
-+#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_BASE_STRICT_P (REGNO)
-+
-+#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_INDEX_STRICT_P (REGNO)
-+
-+#define REG_OK_FOR_BASE_STRICT_P(X)     REGNO_OK_FOR_BASE_STRICT_P (REGNO (X))
-+#define REG_OK_FOR_BASE_NONSTRICT_P(X)  REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (X))
-+#define REG_OK_FOR_INDEX_STRICT_P(X)    REGNO_OK_FOR_INDEX_STRICT_P (REGNO (X))
-+#define REG_OK_FOR_INDEX_NONSTRICT_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (X))
-+
-+#ifndef REG_OK_STRICT
-+#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_NONSTRICT_P(X)
-+#ifdef USE_INDEX_REGISTERS
-+#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_NONSTRICT_P(X)
-+#else
-+#define REG_OK_FOR_INDEX_P(X)    0
-+#endif
-+#else
-+#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_STRICT_P (X)
-+#ifdef USE_INDEX_REGISTERS
-+#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_STRICT_P (X)
-+#else
-+#define REG_OK_FOR_INDEX_P(X)    0
-+#endif
-+#endif
-+
-+/* Maximum number of registers that can appear in a valid memory address */
-+#ifdef USE_INDEX_REGISTERS
-+#define MAX_REGS_PER_ADDRESS 2
-+#else
-+#define MAX_REGS_PER_ADDRESS 1
-+#endif
-+
-+/* 1 if X is an rtx for a constant that is a valid address.
-+ * We allow any constant, plus the sum of any two constants (this allows
-+ * offsetting a symbol ref) */
-+#define CONSTANT_ADDRESS_P(X) \
-+	((CONSTANT_P (X)) \
-+	|| ((GET_CODE (X) == PLUS) \
-+	      && (CONSTANT_P (XEXP (X, 0))) && (CONSTANT_P (XEXP (X, 1)))))
-+
-+/* Nonzero if the constant value X is a legitimate general operand.
-+   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
-+/* Any single-word constant is ok; the only contexts
-+   allowing general_operand of mode DI or DF are movdi and movdf. */
-+#define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
-+
-+/* Nonzero if the X is a legitimate immediate operand in PIC mode. */
-+#define LEGITIMATE_PIC_OPERAND_P(X)	!symbolic_operand (X, VOIDmode)
-+
-+/*--------------------------------------------------------------
-+	Test for valid memory addresses
-+--------------------------------------------------------------*/
-+/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
-+   that is a valid memory address for an instruction.
-+   The MODE argument is the machine mode for the MEM expression
-+   that wants to use this address. */
-+
-+/*--------------------------------------------------------------
-+   Valid addresses are either direct or indirect (MEM) versions
-+   of the following forms.
-+	constant		N
-+	register		,X
-+	constant indexed	N,X
-+	accumulator indexed	D,X
-+	auto_increment		,X++
-+	auto_decrement		,--X
-+--------------------------------------------------------------*/
-+
-+#define REGISTER_ADDRESS_P(X) \
-+  (REG_P (X) && REG_OK_FOR_BASE_P (X))
-+
-+#define EXTENDED_ADDRESS_P(X) \
-+    CONSTANT_ADDRESS_P (X) \
-+
-+#define LEGITIMATE_BASE_P(X) \
-+  ((REG_P (X) && REG_OK_FOR_BASE_P (X))	\
-+   || (GET_CODE (X) == SIGN_EXTEND			\
-+       && GET_CODE (XEXP (X, 0)) == REG			\
-+       && GET_MODE (XEXP (X, 0)) == HImode		\
-+       && REG_OK_FOR_BASE_P (XEXP (X, 0))))
-+
-+#define LEGITIMATE_OFFSET_P(X) \
-+    (CONSTANT_ADDRESS_P (X) || (REG_P (X) && REG_OK_FOR_INDEX_P (X)))
-+
-+/* 1 if X is the sum of a base register and an offset. */
-+#define INDEXED_ADDRESS(X) \
-+   ((GET_CODE (X) == PLUS \
-+       && LEGITIMATE_BASE_P (XEXP (X, 0)) \
-+       && LEGITIMATE_OFFSET_P (XEXP (X, 1))) \
-+   || (GET_CODE (X) == PLUS \
-+       && LEGITIMATE_BASE_P (XEXP (X, 1)) \
-+       && LEGITIMATE_OFFSET_P (XEXP (X, 0))))
-+
-+#define STACK_REG_P(X) (REG_P(X) && REGNO(X) == HARD_S_REGNUM)
-+
-+#define STACK_PUSH_P(X) \
-+   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == PRE_DEC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
-+
-+#define STACK_POP_P(X) \
-+   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == POST_INC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
-+
-+#define PUSH_POP_ADDRESS_P(X) \
-+    (((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
-+	&& (LEGITIMATE_BASE_P (XEXP (X, 0))))
-+
-+/* Go to ADDR if X is a valid address. */
-+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-+{ \
-+  if (REGISTER_ADDRESS_P(X)) goto ADDR; \
-+  if (PUSH_POP_ADDRESS_P (X)) goto ADDR; \
-+  if (EXTENDED_ADDRESS_P (X)) goto ADDR; \
-+  if (INDEXED_ADDRESS (X)) goto ADDR; \
-+  if (MEM_P (X) && REGISTER_ADDRESS_P(XEXP (X, 0))) goto ADDR; \
-+  if (MEM_P (X) && PUSH_POP_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
-+  if (MEM_P (X) && EXTENDED_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
-+  if (MEM_P (X) && INDEXED_ADDRESS (XEXP (X, 0))) goto ADDR; \
-+}
-+
-+/*--------------------------------------------------------------
-+	Address Fix-up
-+--------------------------------------------------------------*/
-+/* Go to LABEL if ADDR (a legitimate address expression)
-+   has an effect that depends on the machine mode it is used for.
-+	In the latest GCC, this case is already handled by the core code
-+	so no action is required here. */
-+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
-+
-+
-+/*--------------------------------------------------------------
-+	Miscellaneous Parameters
-+--------------------------------------------------------------*/
-+/* Specify the machine mode that this machine uses
-+   for the index in the tablejump instruction.  */
-+#define CASE_VECTOR_MODE Pmode
-+
-+/* Define this as 1 if `char' should by default be signed; else as 0.  */
-+#define DEFAULT_SIGNED_CHAR 0
-+
-+/* This flag, if defined, says the same insns that convert to a signed fixnum
-+   also convert validly to an unsigned one.  */
-+#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
-+
-+/* Max number of bytes we can move from memory to memory/register
-+   in one reasonably fast instruction.  */
-+#define MOVE_MAX 2
-+
-+/* Int can be 8 or 16 bits (default is 16) */
-+#define INT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
-+
-+/* Short is always 16 bits */
-+#define SHORT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
-+
-+/* Size (bits) of the type "long" on target machine */
-+#define LONG_TYPE_SIZE (TARGET_BYTE_INT ? 16 : 32)
-+
-+/* Size (bits) of the type "long long" on target machine */
-+#define LONG_LONG_TYPE_SIZE 32
-+
-+/* Size (bits) of the type "char" on target machine */
-+#define CHAR_TYPE_SIZE 8
-+
-+/* Size (bits) of the type "float" on target machine */
-+#define FLOAT_TYPE_SIZE 32
-+
-+/* Size (bits) of the type "double" on target machine.
-+ * Note that the C standard does not require that doubles
-+ * hold any more bits than float.  Since the 6809 has so few
-+ * registers, we cannot really support more than 32-bits. */
-+#define DOUBLE_TYPE_SIZE 32 
-+
-+/* Size (bits) of the type "long double" on target machine */
-+#define LONG_DOUBLE_TYPE_SIZE 32
-+
-+/* Define the type used for "size_t".  With a 64KB address space,
-+ * only a 16-bit value here makes sense. */
-+#define SIZE_TYPE (TARGET_BYTE_INT ? "long unsigned int" : "unsigned int")
-+
-+/* Likewise, the difference between two pointers is also a 16-bit
-+ * signed value. */
-+#define PTRDIFF_TYPE (TARGET_BYTE_INT ? "long int" : "int")
-+
-+/* Nonzero if access to memory by bytes is slow and undesirable.  */
-+#define SLOW_BYTE_ACCESS 0
-+
-+/* Define if shifts truncate the shift count
-+   which implies one can omit a sign-extension or zero-extension
-+   of a shift count.  */
-+#define SHIFT_COUNT_TRUNCATED 0
-+
-+/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
-+   is done just by pretending it is already truncated.  */
-+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-+
-+/* It is as good to call a constant function address as to
-+   call an address kept in a register. */
-+#define NO_FUNCTION_CSE
-+
-+/* Specify the machine mode that pointers have.
-+   After generation of rtl, the compiler makes no further distinction
-+   between pointers and any other objects of this machine mode.  */
-+#define Pmode HImode
-+
-+/* A function address in a call instruction
-+   is a byte address (for indexing purposes)
-+   so give the MEM rtx a byte's mode.  */
-+#define FUNCTION_MODE HImode
-+
-+/* Define the cost of moving a value from a register in CLASS1
-+ * to CLASS2, of a given MODE.
-+ *
-+ * On the 6809, hard register transfers are all basically equivalent.
-+ * But soft register moves are treated more like memory moves. */
-+#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
-+	(((CLASS1 == M_REGS) || (CLASS2 == M_REGS)) ? 4 : 7)
-+
-+/* Define the cost of moving a value between a register and memory. */
-+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 5
-+
-+/* Check a `double' value for validity for a particular machine mode.  */
-+
-+#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
-+  ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
-+
-+
-+/*--------------------------------------------------------------
-+	machine-dependent
-+--------------------------------------------------------------*/
-+/* Tell final.c how to eliminate redundant test instructions.  */
-+
-+/* Here we define machine-dependent flags and fields in cc_status
-+   (see `conditions.h').  */
-+
-+/* Store in cc_status the expressions
-+   that the condition codes will describe
-+   after execution of an instruction whose pattern is EXP.
-+   Do not alter them if the instruction would not alter the cc's.  */
-+
-+/* On the 6809, most of the insns to store in an address register
-+   fail to set the cc's.  However, in some cases these instructions
-+   can make it possibly invalid to use the saved cc's.  In those
-+   cases we clear out some or all of the saved cc's so they won't be used.  */
-+
-+#define NOTICE_UPDATE_CC(EXP, INSN) \
-+  notice_update_cc((EXP), (INSN))
-+
-+/*****************************************************************************
-+**
-+** pragma support
-+**
-+*****************************************************************************/
-+
-+#if 0
-+#define REGISTER_TARGET_PRAGMAS() \
-+do { \
-+	extern void pragma_section PARAMS ((cpp_reader *)); \
-+	c_register_pragma (0, "section", pragma_section); \
-+} while (0)
-+
-+#endif
-+
-+/*--------------------------------------------------------------
-+	ASSEMBLER FORMAT
-+--------------------------------------------------------------*/
-+
-+#define FMT_HOST_WIDE_INT "%ld"
-+
-+/* Output to assembler file text saying following lines
-+   may contain character constants, extra white space, comments, etc.  */
-+#define ASM_APP_ON ";----- asm -----\n"
-+
-+/* Output to assembler file text saying following lines
-+   no longer contain unusual constructs.  */
-+#define ASM_APP_OFF ";--- end asm ---\n"
-+
-+/* Use a semicolon to begin a comment. */
-+#define ASM_COMMENT_START "; "
-+
-+/* Output assembly directives to switch to section 'name' */
-+#undef TARGET_ASM_NAMED_SECTION
-+#define TARGET_ASM_NAMED_SECTION	m6809_asm_named_section
-+
-+#undef TARGET_HAVE_NAMED_SECTION
-+#define TARGET_HAVE_NAMED_SECTION m6809_have_named_section
-+
-+/* Output before read-only data.  */
-+#define TEXT_SECTION_ASM_OP (code_section_op)
-+
-+/* Output before writable data.  */
-+#define DATA_SECTION_ASM_OP (data_section_op)
-+
-+/* Output before uninitialized data.  */
-+#define BSS_SECTION_ASM_OP (bss_section_op)
-+
-+/* Support the ctors and dtors sections for g++.  */
-+ 
-+#undef CTORS_SECTION_ASM_OP
-+#define CTORS_SECTION_ASM_OP    "\t.area .ctors"
-+#undef DTORS_SECTION_ASM_OP
-+#define DTORS_SECTION_ASM_OP    "\t.area .dtors"
-+
-+
-+#undef DO_GLOBAL_CTORS_BODY
-+#undef DO_GLOBAL_DTORS_BODY
-+
-+#define HAS_INIT_SECTION
-+
-+/* This is how to output an assembler line
-+   that says to advance the location counter
-+   to a multiple of 2**LOG bytes.  */
-+
-+#define ASM_OUTPUT_ALIGN(FILE,LOG) \
-+  if ((LOG) > 1) \
-+    fprintf (FILE, "\t.bndry %u\n", 1 << (LOG))
-+
-+/* The .set foo,bar construct doesn't work by default */
-+#undef SET_ASM_OP
-+#define ASM_OUTPUT_DEF(FILE, LABEL1, LABEL2)			\
-+  do								\
-+    {								\
-+      fputc ('\t', FILE);					\
-+      assemble_name (FILE, LABEL1);				\
-+      fputs (" = ", FILE);					\
-+      assemble_name (FILE, LABEL2);				\
-+      fputc ('\n', FILE);					\
-+    }								\
-+  while (0)
-+
-+/* How to refer to registers in assembler output.
-+   This sequence is indexed by compiler's hard-register-number (see above).  */
-+#define MNAME(x) [SOFT_M0_REGNUM+(x)] = "*m" C_STRING(x) ,
-+
-+#define REGISTER_NAMES { \
-+	[HARD_D_REGNUM]= "d", \
-+	[HARD_X_REGNUM]= "x", \
-+	[HARD_Y_REGNUM]= "y", \
-+	[HARD_U_REGNUM]= "u", \
-+	[HARD_S_REGNUM]= "s", \
-+	[HARD_PC_REGNUM]= "pc", \
-+	[HARD_A_REGNUM]= "a", \
-+	[HARD_B_REGNUM]= "b", \
-+	[HARD_CC_REGNUM]= "cc",\
-+	[HARD_DP_REGNUM]= "dp", \
-+	[SOFT_FP_REGNUM]= "soft_fp", \
-+	[SOFT_AP_REGNUM]= "soft_ap", \
-+	MNAME(0) MNAME(1) MNAME(2) MNAME(3) \
-+	MNAME(4) MNAME(5) MNAME(6) MNAME(7) \
-+	[HARD_RSVD1_REGNUM] = "-", \
-+	[HARD_Z_REGNUM] = "z" /* bit 2 of CC */ }
-+
-+/*****************************************************************************
-+**
-+** Debug Support
-+**
-+*****************************************************************************/
-+
-+/* Default to DBX-style debugging */
-+#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
-+
-+#define DBX_DEBUGGING_INFO
-+
-+#define DEFAULT_GDB_EXTENSIONS 0
-+
-+#define ASM_STABS_OP ";\t.stabs\t"
-+#define ASM_STABD_OP ";\t.stabd\t"
-+#define ASM_STABN_OP ";\t.stabn\t"
-+
-+#define DBX_CONTIN_LENGTH 54
-+
-+#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(ASMFILE, FILENAME) \
-+do { \
-+	const char *p = FILENAME; \
-+	while ((p = strchr (p, '/')) != NULL) { \
-+		p = FILENAME = p+1; \
-+	} \
-+  fprintf (ASMFILE, "%s", ASM_STABS_OP); \
-+  output_quoted_string (ASMFILE, FILENAME); \
-+  fprintf (ASMFILE, ",%d,0,0,", N_SO); \
-+  assemble_name (ASMFILE, ltext_label_name); \
-+  fputc ('\n', ASMFILE); \
-+  switch_to_section (text_section); \
-+  (*targetm.asm_out.internal_label) (ASMFILE, "Ltext", 0); \
-+} while (0)
-+
-+/* With -g, GCC sometimes outputs string literals that are longer than
-+ * the assembler can handle.  Without actual debug support, these are
-+ * not really required.  Redefine the function to output strings to
-+ * output as much as possible. */
-+#define OUTPUT_QUOTED_STRING(FILE, STR) m6809_output_quoted_string (FILE, STR)
-+
-+/*****************************************************************************
-+**
-+** Output and Generation of Labels
-+**
-+*****************************************************************************/
-+
-+/* Prefixes for various assembly-time objects */
-+
-+#define REGISTER_PREFIX ""
-+
-+#define LOCAL_LABEL_PREFIX ""
-+
-+#define USER_LABEL_PREFIX "_"
-+
-+#define IMMEDIATE_PREFIX "#"
-+
-+/* This is how to output the definition of a user-level label named NAME,
-+   such as the label on a static function or variable NAME.  */
-+
-+#define ASM_OUTPUT_LABEL(FILE,NAME) \
-+do { \
-+  if (section_changed) { \
-+	  fprintf (FILE, "\n%s\n\n", code_section_op); \
-+     section_changed = 0; \
-+  } \
-+  assemble_name (FILE, NAME); \
-+  fputs (":\n", FILE); \
-+} while (0)
-+
-+/* This is how to output the label for a function definition.  It
-+   invokes ASM_OUTPUT_LABEL, but may examine the DECL tree node for
-+	other properties. */
-+#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
-+  m6809_declare_function_name (FILE,NAME,DECL)
-+
-+/* This is how to output a command to make the user-level label
-+    named NAME defined for reference from other files.  */
-+
-+#define GLOBAL_ASM_OP "\t.globl "
-+
-+/* This is how to output a reference to a user label named NAME. */
-+#define ASM_OUTPUT_LABELREF(FILE,NAME) \
-+  fprintf (FILE, "_%s", NAME)
-+
-+/* This is how to output a reference to a symbol ref
-+ * Check to see if the symbol is in the direct page */
-+#define ASM_OUTPUT_SYMBOL_REF(FILE,sym) \
-+{ \
-+	print_direct_prefix (FILE, sym); \
-+	assemble_name (FILE, XSTR (sym, 0)); \
-+}
-+
-+/* External references aren't necessary, so don't emit anything */
-+#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)
-+
-+/* This is how to store into the string LABEL
-+   the symbol_ref name of an internal numbered label where
-+   PREFIX is the class of label and NUM is the number within the class.
-+   This is suitable for output with `assemble_name'.  */
-+#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
-+  sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long int)NUM)
-+
-+/* This is how to output an assembler line defining an `int' constant.  */
-+#define ASM_OUTPUT_INT(FILE,VALUE) \
-+( fprintf (FILE, "\t.word "), \
-+  output_addr_const (FILE, (VALUE)), \
-+  fprintf (FILE, "\n"))
-+
-+/* Likewise for `char' and `short' constants.  */
-+#define ASM_OUTPUT_SHORT(FILE,VALUE) \
-+( fprintf (FILE, "\t.word "), \
-+  output_addr_const (FILE, (VALUE)), \
-+  fprintf (FILE, "\n"))
-+
-+/* This is how to output a string. */ 
-+#define ASM_OUTPUT_ASCII(FILE,STR,SIZE) m6809_output_ascii (FILE, STR, SIZE)
-+
-+/* This is how to output an insn to push a register on the stack.
-+   It need not be very fast code.  */
-+
-+#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
-+   fprintf (FILE, "\tpshs\t%s\n", reg_names[REGNO])
-+
-+/* This is how to output an insn to pop a register from the stack.
-+   It need not be very fast code.  */
-+
-+#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
-+   fprintf (FILE, "\tpuls\t%s\n", reg_names[REGNO])
-+
-+/* This is how to output an element of a case-vector that is absolute. */
-+
-+#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
-+  fprintf (FILE, "\t.word L%u\n", VALUE)
-+
-+/* This is how to output an element of a case-vector that is relative. */
-+
-+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-+  fprintf (FILE, "\t.word L%u-L%u\n", VALUE, REL)
-+
-+
-+/*****************************************************************************
-+**
-+** Assembler Commands for Alignment
-+**
-+*****************************************************************************/
-+
-+/* ASM_OUTPUT_SKIP is supposed to zero initialize the data.
-+ * So use the .byte and .word directives instead of .blkb */
-+#define ASM_OUTPUT_SKIP(FILE,SIZE) \
-+  do { \
-+    int __size = SIZE; \
-+    while (__size > 0) { \
-+      if (__size >= 2) \
-+      { \
-+        fprintf (FILE, "\t.word\t0\t;skip space %d\n", __size); \
-+        __size -= 2; \
-+      } \
-+      else \
-+      { \
-+        fprintf (FILE, "\t.byte\t0\t;skip space\n"); \
-+        __size--; \
-+      } \
-+    } \
-+  } while (0)
-+
-+/* This says how to output an assembler line
-+   to define a global common symbol.  */
-+
-+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
-+  do { \
-+  switch_to_section (bss_section); \
-+  fputs ("\t.globl\t", FILE); \
-+  assemble_name ((FILE), (NAME)); \
-+  fputs ("\n", FILE); \
-+  assemble_name ((FILE), (NAME)); \
-+  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
-+
-+/* This says how to output an assembler line
-+   to define a local common symbol.  */
-+
-+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
-+do { \
-+  switch_to_section (bss_section); \
-+  assemble_name ((FILE), (NAME)); \
-+  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
-+
-+/* Store in OUTPUT a string (made with alloca) containing
-+   an assembler-name for a local static variable named NAME.
-+   LABELNO is an integer which is different for each call.  */
-+
-+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-+( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
-+  sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long int)(LABELNO)))
-+
-+/* Print an instruction operand X on file FILE.
-+   CODE is the code from the %-spec for printing this operand.
-+   If `%z3' was used to print operand 3, then CODE is 'z'. */
-+#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
-+
-+/* Print a memory operand whose address is X, on file FILE. */
-+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
-+
-+/* Don't let stack pushes build up too much. */
-+#define MAX_PENDING_STACK 8
-+
-+/* Define values for builtin operations */
-+enum m6809_builtins
-+{
-+	M6809_SWI,
-+	M6809_SWI2,
-+	M6809_SWI3,
-+	M6809_CWAI,
-+	M6809_SYNC,
-+	M6809_ADD_CARRY,
-+	M6809_SUB_CARRY,
-+	M6809_ADD_DECIMAL,
-+	M6809_NOP,
-+	M6809_BLOCKAGE
-+};
-+
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/m6809.md gcc-4.6.1/gcc/config/m6809/m6809.md
---- gcc-4.6.1-orig/gcc/config/m6809/m6809.md	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/m6809.md	2011-09-21 20:40:01.287068005 -0600
-@@ -0,0 +1,2359 @@
-+;; GCC machine description for Motorola 6809
-+;; Copyright (C) 1989, 2005, 2006, 2007, 2008,
-+;; 2009 Free Software Foundation, Inc.
-+;;
-+;; Mostly by Brian Dominy (brian@oddchange.com) with substantial renovations
-+;; by William Astle (lost@l-w.ca).
-+;;
-+;; Based on earlier work by Tom Jones (jones@sal.wisc.edu) and
-+;; Matthias Doerfel (msdoerfe@informatik.uni-erlangen.de)
-+;;
-+;; 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/>.
-+;;
-+;; General information:
-+;; --------------------
-+;; * This backend is mostly a rewrite from earlier (3.1.1 and before)
-+;; versions.
-+;;
-+;; * The 'A' and 'B' registers are treated as a single register by the
-+;; register allocator; hence, the instruction templates assume that
-+;; both can be modified if either one is available for use.  No
-+;; attempt is made to split instructions to refer to a particular half
-+;; of the register.  It is always referred to as the 'D' register, even
-+;; in QImode (when it will be displayed as 'B').
-+;;
-+;; * There is full support for proper branch instruction generation,
-+;; based on instruction lengths.  However, many instruction patterns
-+;; are still overloaded to emit lots of real instructions, which can
-+;; make the length calculation difficult; in those cases, I've tried
-+;; to be pessimistic and assume the worst-case.
-+;;
-+;; * The instruction type attributes are only defined for branch
-+;; vs. non branch instructions for now, since there is seemingly no
-+;; reason to define these for other types anyway.
-+;;
-+;; * The limited number of total registers presents the greatest
-+;; challenge.  There are 'soft registers' -- memory locations
-+;; used to simulate real regs -- which can be helpful.
-+;;
-+;; * Position-independent code (PIC) is supported and has been tested
-+;; but not to the extent of absolute code generation.
-+;;
-+;; * All of the 6809 special opcodes, e.g. SWI and SYNC, are defined
-+;; as UNSPEC instructions, and can be accessed from C code using
-+;; __builtin_xxxx() style functions.
-+;;
-+;; What still needs to be done:
-+;; ----------------------------
-+;; * Replace remaining instances of (define_peephole) with
-+;; (define_peephole2), or remove them completely if they are not
-+;; matching anyway.  Add more peepholes for things actually encountered.
-+;;
-+;; * Indexing addressing can lead to crashes in complex functions when
-+;; register pressure is high.  Only the 'D' register can actually be
-+;; used as an index register, and its demand by other instructions
-+;; can sometimes mean that it is impossible to satisfy constraints.
-+;; Currently, indexing is completely disabled to avoid these types
-+;; of problems, although code is slightly more inefficient in some
-+;; working cases.
-+;;
-+;; * 32-bit math is terribly inefficient.
-+;;
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Constants
-+;;--------------------------------------------------------------------
-+
-+;
-+; Define constants for hard register numbers.
-+;
-+(define_constants [
-+  (HARD_RSVD1_REGNUM 0)
-+  (HARD_X_REGNUM 1) (HARD_Y_REGNUM 2) (HARD_U_REGNUM 3)
-+  (HARD_S_REGNUM 4) (HARD_PC_REGNUM 5) (HARD_D_REGNUM 6)
-+  (HARD_Z_REGNUM 7)
-+  (HARD_A_REGNUM 8) (HARD_B_REGNUM 9)
-+  (HARD_CC_REGNUM 10) (HARD_DP_REGNUM 11)
-+  (SOFT_FP_REGNUM 12) (SOFT_AP_REGNUM 13)
-+  (SOFT_M0_REGNUM 14) (SOFT_M1_REGNUM 15)
-+  (SOFT_M2_REGNUM 16) (SOFT_M3_REGNUM 17)
-+])
-+
-+
-+;
-+; The range in which a short branch insn can be used.
-+;
-+(define_constants [
-+  (MIN_SHORT_BRANCH_OFFSET -127)
-+  (MAX_SHORT_BRANCH_OFFSET 128)
-+])
-+
-+
-+;
-+; The lengths of various types of real 6809 instructions.
-+;
-+; By default, ordinary insns are 4 bytes long.  This is often not
-+; right, and the insn patterns below will redefine this to the
-+; correct value.
-+;
-+; Branch instruction lengths (conditional and unconditionals) are
-+; well known and declared here.  The short insns are used when the
-+; offset is within the range declared above (between MIN_SHORT
-+; and MAX_SHORT) ; otherwise the long form is used.
-+;
-+(define_constants [
-+  (DEFAULT_INSN_LENGTH 4)
-+  (SHORT_CBRANCH_LENGTH 2)
-+  (LONG_CBRANCH_LENGTH 4)
-+  (SHORT_BRANCH_LENGTH 2)
-+  (LONG_BRANCH_LENGTH 3)
-+])
-+
-+
-+;
-+; Constants for insn cycle counts.
-+; Note that these counts all assume 1-byte opcodes.  2-byte
-+; opcodes require 1 extra cycles for fetching the extra byte.
-+;
-+(define_constants [
-+  ;; The default insn length, when it cannot be calculated.
-+  ;; Take a conservative approach and estimate high.
-+  (DEFAULT_INSN_CYCLES 10)
-+
-+  ;; Cycle counts for ALU and load operations.
-+  (ALU_INHERENT_CYCLES 2)
-+  (ALU_IMMED_CYCLES 2)
-+  (ALU_DIRECT_CYCLES 4)
-+  (ALU_INDEXED_BASE_CYCLES 4)
-+  (ALU_EXTENDED_CYCLES 5)
-+
-+  ;; If an ALU operation is on a 16-bit register (D), then
-+  ;; add this number of cycles to the total count.
-+  (ALU_16BIT_CYCLES 2)
-+
-+  ;; A load of a 16-bit register incurs this extra amount.
-+  (LOAD_16BIT_CYCLES 1)
-+
-+  ;; Cycle counts for memory-only operations (bit shifts, clear, test)
-+  (MEM_DIRECT_CYCLES 6)
-+  (MEM_INDEXED_BASE_CYCLES 6)
-+  (MEM_EXTENDED_CYCLES 7)
-+
-+  ;; Cycle count for any reg-reg transfer (regardless of size)
-+  (EXG_CYCLES 8)
-+  (TFR_CYCLES 6)
-+
-+  ;; Cycle count for a condition code update (andcc/orcc)
-+  (CC_CYCLES 3)
-+
-+  (JMP_DIRECT_CYCLES 3)
-+  (JMP_INDEXED_BASE_CYCLES 3)
-+  (JMP_EXTENDED_CYCLES 4)
-+
-+  (JSR_DIRECT_CYCLES 7)
-+  (JSR_INDEXED_BASE_CYCLES 7)
-+  (JSR_EXTENDED_CYCLES 8)
-+
-+  (LEA_BASE_CYCLES 4)
-+
-+  ;; Cycle count for a psh/pul operations.  Add to this the
-+  ;; total number of bytes moved for the correct count.
-+  (PSH_PUL_CYCLES 5)
-+
-+  ;; Miscellaneous cycle counts
-+  (CWAI_CYCLES 20)
-+  (MUL_CYCLES 11)
-+  (NOP_CYCLES 2)
-+  (RTI_CYCLES 15)
-+  (RTS_CYCLES 5)
-+  (SWI_CYCLES 20)
-+  (SYNC_CYCLES 4)
-+])
-+
-+
-+;
-+; An enumeration of values for each "unspec"; i.e. unspecified
-+; instruction.  These represent insns that are meaningful on the
-+; 6809 but which have no intrinsic meaning to GCC itself.
-+; These insns can be generated explicitly using the __builtin_xxx
-+; syntax; they are also implicitly generated by the backend
-+; as needed to implement other insns.
-+;
-+(define_constants [
-+  (UNSPEC_BLOCKAGE 0)
-+  (UNSPEC_PUSH_RS 1)
-+  (UNSPEC_POP_RS 2)
-+  (UNSPEC_SWI 3)
-+  (UNSPEC_CWAI 4)
-+  (UNSPEC_ADD_CARRY 5)
-+  (UNSPEC_SUB_CARRY 6)
-+  (UNSPEC_SYNC 7)
-+  (UNSPEC_ADD_DECIMAL 8)
-+])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Predicates
-+;;--------------------------------------------------------------------
-+
-+(include "predicates.md")
-+
-+;;--------------------------------------------------------------------
-+;;-  Attributes
-+;;--------------------------------------------------------------------
-+
-+;;
-+;; The type attribute is used to distinguish between different
-+;; types of branch instructions, so that their lengths can be
-+;; calculated correctly.
-+;;
-+(define_attr "type" "branch,cbranch,unknown" (const_string "unknown"))
-+
-+;;
-+;; The length of a branch instruction is calculated based on how
-+;; far away the branch target is.  Lengths of other insns default
-+;; to 4.  set_attr is used in instruction templates to specify
-+;; the length when it is known exactly.  When not sure, err on
-+;; the high side to avoid compile errors.
-+;;
-+(define_attr "length" ""
-+  (cond [
-+    (eq_attr "type" "branch")
-+    (if_then_else (lt (minus (match_dup 0) (pc))
-+                      (const_int MIN_SHORT_BRANCH_OFFSET))
-+      (const_int LONG_BRANCH_LENGTH)
-+        (if_then_else (gt (minus (match_dup 0) (pc))
-+                          (const_int MAX_SHORT_BRANCH_OFFSET))
-+          (const_int LONG_BRANCH_LENGTH)
-+          (const_int SHORT_BRANCH_LENGTH)))
-+    (eq_attr "type" "cbranch")
-+    (if_then_else (lt (minus (match_dup 0) (pc))
-+                      (const_int MIN_SHORT_BRANCH_OFFSET))
-+      (const_int LONG_CBRANCH_LENGTH)
-+        (if_then_else (gt (minus (match_dup 0) (pc))
-+                          (const_int MAX_SHORT_BRANCH_OFFSET))
-+          (const_int LONG_CBRANCH_LENGTH)
-+          (const_int SHORT_CBRANCH_LENGTH)))
-+  ] (const_int DEFAULT_INSN_LENGTH)))
-+
-+
-+;;
-+;; The default attributes for 'asm' statements.
-+;; The default length is the longest possible single 6809 instruction,
-+;; which is 5 bytes.  GCC will automatically multiply this by the
-+;; number of real insns contained in an asm statement.
-+;;
-+(define_asm_attributes
-+  [(set_attr "length" "5")
-+   (set_attr "type" "unknown")])
-+
-+;;
-+;; An attribute for the number of cycles that it takes an instruction
-+;; to execute.
-+;;
-+(define_attr "cycles" "" (const_int DEFAULT_INSN_CYCLES))
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Instruction patterns.  When multiple patterns apply,
-+;;- the first one in the file is chosen.
-+;;-
-+;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-+;;-
-+;;- Note: NOTICE_UPDATE_CC in m6809.h handles condition code updates
-+;;- for most instructions.
-+;;--------------------------------------------------------------------
-+
-+;;--------------------------------------------------------------------
-+;;-  Test
-+;;--------------------------------------------------------------------
-+
-+;; cmpx is 3 bytes, not 4
-+(define_insn "*tsthi_x"
-+  [(set (cc0) (match_operand:HI 0 "register_operand_x" "v"))]
-+  ""
-+  "cmpx\t#0"
-+  [(set_attr "length" "3")])
-+
-+;; subd #0 is 3 bytes, better than cmpd #0 which is 4 bytes
-+(define_insn "*tsthi_d"
-+  [(set (cc0) (match_operand:HI 0 "register_operand_d" "d"))]
-+  ""
-+  "subd\t#0"
-+  [(set_attr "length" "3")])
-+
-+(define_insn "*tsthi"
-+  [(set (cc0) (match_operand:HI 0 "register_operand" "a"))]
-+  ""
-+  "cmp%0\t#0"
-+   [(set_attr "length" "4")])
-+
-+(define_insn "*bitqi3"
-+  [(set (cc0)
-+    (and:QI (match_operand:QI 0 "register_operand" "%q")
-+      (match_operand:QI 1 "general_operand" "mi")))]
-+  ""
-+  "bit%0\t%1"
-+  [(set_attr "length" "3")])
-+
-+
-+(define_insn "tstqi"
-+  [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "q,mt"))]
-+  ""
-+  "@
-+   tst%0
-+   tst\t%0"
-+   [(set_attr "length" "1,3")])
-+
-+;;--------------------------------------------------------------------
-+;;- Compare instructions
-+;;--------------------------------------------------------------------
-+
-+;; - cmphi for register to memory or register compares
-+(define_insn "cmphi"
-+  [(set (cc0)
-+    (compare
-+      (match_operand:HI 0 "general_operand" "da, mi, ??Ud")
-+      (match_operand:HI 1 "general_operand" "mi, da,  dU")))]
-+  ""
-+{
-+  if ((REG_P (operands[0])) && (REG_P (operands[1]))) {
-+    output_asm_insn ("pshs\t%1\t;cmphi: R:%1 with R:%0", operands);
-+    return "cmp%0\t,s++\t;cmphi:";
-+  }
-+  if (GET_CODE (operands[0]) == REG)
-+    return "cmp%0\t%1\t;cmphi:";
-+  else {
-+    cc_status.flags |= CC_REVERSED;
-+    return "cmp%1\t%0\t;cmphi:(R)";
-+  }
-+}
-+  [(set_attr "length" "5,5,7")])
-+
-+
-+(define_insn "cmpqi"
-+  [(set (cc0)
-+    (compare (match_operand:QI 0 "whole_general_operand" "q,q, q,O,mt,K")
-+    (match_operand:QI 1 "whole_general_operand"          "O,mt,K,q,q, q")))]
-+  ""
-+{
-+    if (REG_P (operands[0]) && !M_REG_P (operands[0]))
-+    {
-+      if (operands[1] == const0_rtx)
-+        return "tst%0\t;cmpqi:(ZERO)";
-+      else
-+        return "cmp%0\t%1\t;cmpqi:";
-+    }
-+    else
-+    {
-+      cc_status.flags |= CC_REVERSED;
-+
-+      if (operands[0] == const0_rtx)
-+        return "tst%1\t;cmpqi:(RZERO)";
-+      else
-+        return "cmp%1\t%0\t;cmpqi:(R)";
-+    }
-+}
-+   [(set_attr "length" "1,3,2,1,3,2")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Compare/branch pattern
-+;;--------------------------------------------------------------------
-+
-+(define_expand "cbranchhi4"
-+  [(set (cc0)
-+    (compare
-+      (match_operand:HI 1 "general_operand" "da, mi, ??Ud")
-+      (match_operand:HI 2 "general_operand" "mi, da,  dU")))
-+   (set (pc)
-+     (if_then_else
-+        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
-+        (label_ref (match_operand 3 "" ""))
-+        (pc)))]
-+   ""
-+   ""
-+)
-+
-+(define_expand "cbranchqi4"
-+  [(set (cc0)
-+    (compare
-+      (match_operand:QI 1 "whole_general_operand" "q,q, q,O,mt,K")
-+      (match_operand:QI 2 "whole_general_operand" "O,mt,K,q,q, q")))
-+   (set (pc)
-+     (if_then_else
-+        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
-+        (label_ref (match_operand 3 "" ""))
-+        (pc)))]
-+   ""
-+   ""
-+)
-+
-+;;--------------------------------------------------------------------
-+;;-  Move
-+;;--------------------------------------------------------------------
-+
-+; this looks good (obviously not finished) but I still see 'movsi'
-+; places in udivsi3 where it's broken
-+; (define_insn "pushsi1"
-+;   [(set (mem:SI (pre_dec (reg:HI HARD_S_REGNUM)))
-+;         (match_operand:SI 0 "general_operand" "o"))
-+;    (set (reg:HI HARD_S_REGNUM)
-+;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int -4))) ]
-+;   ""
-+;   "; pushsi %0"
-+;    [(set_attr "length" "12")])
-+;
-+; (define_insn "popsi1"
-+;   [(set (match_operand:SI 0 "general_operand" "=o")
-+;         (mem:SI (post_inc (reg:HI HARD_S_REGNUM))))
-+;    (set (reg:HI HARD_S_REGNUM)
-+;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int 4))) ]
-+;   ""
-+;   "; popsi %0"
-+;    [(set_attr "length" "12")])
-+
-+; (define_insn "movsi"
-+;   [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
-+;         (match_operand:SI 1 "general_operand"      " oi"))]
-+;   ""
-+;   "; movsi %0 <- %1"
-+;    [(set_attr "length" "1")])
-+
-+; this doesn't work
-+; (define_expand "movsi"
-+;   [(parallel [
-+;      (set (match_operand:SI 0 "nonimmediate_operand" "")
-+;           (match_operand:SI 1 "general_operand" ""))
-+;      (clobber (match_scratch:HI 2 ""))])]
-+;   ""
-+; {
-+;   rtx insn;
-+;   if (STACK_PUSH_P (operands[0]) || STACK_POP_P (operands[1]))
-+;   {
-+;     REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
-+;   }
-+;   insn = emit_move_multi_word (SImode, operands[0], operands[1]);
-+;   DONE;
-+; })
-+
-+
-+(define_expand "movhi"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+    (match_operand:HI 1 "general_operand" ""))]
-+  ""
-+{
-+  /* One of the ops has to be in a register prior to reload */
-+  if (!register_operand (operand0, HImode) &&
-+      !register_operand (operand1, HImode))
-+    operands[1] = copy_to_mode_reg (HImode, operand1);
-+})
-+
-+;;; Try a splitter to handle failure cases where we try to move
-+;;; an immediate constant (zero usually) directly to memory.
-+;;; This absolutely requires an intermediate register.
-+(define_split
-+  [(set (match_operand:HI 0 "memory_operand" "")
-+    (match_operand:HI 1 "immediate_operand"  ""))
-+   (clobber (match_operand:HI 2 "register_operand" ""))]
-+  ""
-+  [(set (match_dup 2) (match_dup 1))
-+   (set (match_dup 0) (match_dup 2))]
-+  "")
-+
-+
-+;;; This would be a nice method for loading from a word array,
-+;;; but it is never generated because the combiner cannot merge
-+;;; more than 3 instructions (there are four here).  This is
-+;;; perhaps better done via a peephole.
-+(define_insn "*movhi_array_load"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=da")
-+    (mem:HI (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B")) (const_int 1))
-+                     (match_operand:HI 2 "immediate_operand" "i"))))
-+   (clobber (match_scratch:HI 3 "=X"))]
-+  ""
-+  "ldx\t%2\;abx\;abx\;ld%0\t,x"
-+   [(set_attr "length" "7")])
-+
-+
-+;;; Optimize the move of a byte to the stack using the pshs instruction
-+;;; instead of a store with pre-increment.
-+(define_insn "movhi_push"
-+  [(set (match_operand:HI 0 "push_operand" "=m")
-+    (match_operand:HI 1 "register_operand" "U"))]
-+  ""
-+  "pshs\t%1"
-+  [(set_attr "length" "2")])
-+
-+
-+(define_insn "*movhi_pic_symbolref"
-+  [(set (match_operand:HI 0 "register_operand" "=a")
-+    (match_operand:HI 1 "symbolic_operand" ""))]
-+  "flag_pic"
-+  "lea%0\t%c1,pcr"
-+   [(set_attr "length" "4")])
-+
-+
-+(define_insn "*movhi_1"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,d,a,ad,tmu")
-+    (match_operand:HI 1 "general_operand"          " a,a,d,tmiu,ad"))]
-+  ""
-+  "@
-+   lea%0\t,%1
-+   tfr\t%1,%0
-+   tfr\t%1,%0
-+   ld%0\t%1
-+   st%1\t%0"
-+   [(set_attr "length" "2,2,2,*,*")])
-+
-+
-+;;; Generated by the combiner to merge an address calculation with
-+;;; a byte load.  We can use the 'abx' instruction here.
-+(define_insn "*movqi_array_load"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
-+    (mem:QI (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B"))
-+                     (match_operand:HI 2 "immediate_operand" "i"))))
-+   (clobber (match_scratch:HI 3 "=X"))]
-+  ""
-+  "ldx\t%2\;abx\;ld%0\t,x"
-+   [(set_attr "length" "6")])
-+
-+
-+;;; Optimize the move of a byte to the stack using the pshs instruction
-+;;; instead of a store with pre-increment.
-+(define_insn "movqi_push"
-+  [(set (match_operand:QI 0 "push_operand" "=m")
-+    (match_operand:QI 1 "register_operand" " q"))]
-+  ""
-+  "pshs\t%1"
-+  [(set_attr "length" "2")])
-+
-+
-+;;; Optimize the move of a byte from the stack using the puls instruction
-+;;; instead of a store with post-decrement.
-+(define_insn "movqi_pop"
-+  [(set (match_operand:QI 0 "register_operand" "=q")
-+    (match_operand:QI 1 "pop_operand" "m"))]
-+  ""
-+  "puls\t%0"
-+  [(set_attr "length" "2")])
-+
-+
-+;;- load low byte of 16-bit data into 8-bit register/memory
-+(define_insn "*mov_lsb"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,m,!q")
-+      (subreg:QI (match_operand:HI 1 "general_operand" "d,m,a,d, U") 1))]
-+  ""
-+  "@
-+   \t;movlsbqihi: D->B
-+   ld%0\t%L1\t;movlsbqihi: msb:%1 -> R:%0
-+   tfr\t%1,d\t;movlsbqihi: R:%1 -> R:%0
-+   stb\t%0\t;movlsbqihi: R:%1 -> %0
-+   pshs\t%1\t;movlsbqihi: R:%1 -> R:%0\;leas\t1,s\;puls\t%0"
-+   [(set_attr "length" "0,*,2,*,6")])
-+
-+
-+;;- load high byte of 16-bit data into 8-bit register/memory
-+(define_insn "*mov_msb"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,q,m,!q")
-+      (subreg:QI (match_operand:HI 1 "general_operand" "d,O,a,m,d, U") 0))]
-+  ""
-+  "@
-+   tfr\ta,b\t;movmsbqihi: D->B
-+   clr%0\t\t;movmsbqihi: ZERO -> R:%0
-+   tfr\t%1,d\t;movmsbqihi: R:%1 -> R:%0\;tfr\ta,b
-+   ld%0\t%L1\t;movmsbqihi: lsb:%1 -> R:%0
-+   sta\t%0\t;movmsbqihi: R:%1 -> %0
-+   pshs\t%1\t;movmsbqihi: R:%1 -> R:%0\;puls\t%0\;leas\t1,s"
-+  [(set_attr "length" "2,1,4,*,*,6")])
-+
-+
-+(define_insn "*movqi_boolean"
-+  [(set (reg:QI HARD_Z_REGNUM)
-+    (match_operand:QI 0 "general_operand" "q,O,i,m"))]
-+  ""
-+  "@
-+   tst%0
-+   andcc\t#~4
-+   orcc\t#4
-+   tst\t%0")
-+
-+
-+(define_insn "movqi"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,tm,q,tm,q,z")
-+    (match_operand:QI 1 "general_operand"          " q,O,O,tmi,q,z,q"))]
-+  ""
-+  "@
-+   tfr\t%1,%0
-+   clr%0
-+   clr\t%0
-+   ld%0\t%1
-+   st%1\t%0
-+   tfr\tcc,%0\;and%0\t#4
-+   tst%0"
-+   [(set_attr "length" "2,1,3,*,*,4,1")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Swap registers
-+;;--------------------------------------------------------------------
-+
-+; Note: 8-bit swap is never needed so it is not defined.
-+
-+(define_insn "swaphi"
-+  [(set (match_operand:HI 0 "register_operand" "+r")
-+    (match_operand:HI 1 "register_operand" "+r"))
-+   (set (match_dup 1) (match_dup 0))]
-+  ""
-+  "exg\t%1,%0"
-+  [(set_attr "length" "2")
-+   (set (attr "cycles") (const_int EXG_CYCLES))])
-+
-+
-+(define_insn "bswaphi2"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+    (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
-+  ""
-+  "exg\ta,b"
-+  [(set_attr "length" "2")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Extension and truncation insns.
-+;;--------------------------------------------------------------------
-+
-+(define_insn "extendqihi2"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+        (sign_extend:HI (match_operand:QI 1 "general_operand" "B")))]
-+  ""
-+  "sex\t\t;extendqihi2: R:%1 -> R:%0"
-+  [(set_attr "length" "1")])
-+
-+
-+(define_insn "zero_extendqihi2"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+        (zero_extend:HI (match_operand:QI 1 "general_operand" "B")))]
-+  ""
-+  "clra\t\t;zero_extendqihi: R:%1 -> R:%0"
-+  [(set_attr "length" "1")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- All kinds of add instructions.
-+;;--------------------------------------------------------------------
-+
-+
-+;;
-+;; gcc's automatic version of addsi3 doesn't know about adcb,adca
-+;; so it is MUCH less efficient.  Define this one ourselves.
-+;;
-+;; TODO - can't always get 'd' for the clobber... allow other registers
-+;; as well and use exg d,R ... exg R,d around the code sequence to
-+;; use others, at a price.  Also consider libcall for this when
-+;; optimizing for size.
-+;;
-+(define_insn "addsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
-+     (plus:SI (match_operand:SI 1 "general_operand" "%o")
-+        (match_operand:SI 2 "general_operand"       " oi")))
-+   (clobber (match_scratch:HI 3 "=d"))]
-+  ""
-+{
-+  m6809_output_addsi3 (PLUS, operands);
-+  return "";
-+}
-+  [(set_attr "length" "21")])
-+
-+
-+; Increment of a 16-bit MEM by 1 can be done without a register.
-+(define_insn "*addhi_mem_1"
-+  [(set (match_operand:HI 0 "memory_operand" "=m")
-+        (plus:HI (match_operand:HI 1 "memory_operand" "0") (const_int 1)))]
-+   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
-+{
-+  rtx xoperands[2];
-+
-+  xoperands[0] = operands[0];
-+  xoperands[1] = adjust_address (operands[0], QImode, 1);
-+
-+  output_asm_insn ("inc\t%1", xoperands);
-+  output_asm_insn ("bne\t__IL%=", xoperands);
-+  output_asm_insn ("inc\t%0\;__IL%=:", xoperands);
-+  return "";
-+}
-+  [(set_attr "length" "7")])
-+
-+
-+; Decrement of a 16-bit MEM by 1 can be done without a register.
-+(define_insn "*addhi_mem_minus1"
-+  [(set (match_operand:HI 0 "memory_operand" "=m")
-+        (plus:HI (match_operand:HI 1 "memory_operand" "0") (const_int -1)))]
-+   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
-+{
-+  rtx xoperands[2];
-+
-+  xoperands[0] = operands[0];
-+  xoperands[1] = adjust_address (operands[0], QImode, 1);
-+
-+  output_asm_insn ("tst\t%1", xoperands);
-+  output_asm_insn ("bne\t__IL%=", xoperands);
-+  output_asm_insn ("dec\t%0", xoperands);
-+  output_asm_insn ("__IL%=:", xoperands);
-+  output_asm_insn ("dec\t%1", xoperands);
-+  return "";
-+}
-+  [(set_attr "length" "7")])
-+
-+
-+; Allow the addition of an 8-bit quantity to a 16-bit quantity
-+; using the LEAX B,Y addressing mode, where X and Y are both
-+; index registers.  This will only get generated via the peephole
-+; which removes a sign extension.
-+(define_insn "*addhi_b"
-+  [(set (match_operand:HI 0 "index_register_operand"       "=a")
-+    (plus:HI(match_operand:HI 1 "index_register_operand"   "%a")
-+    (match_operand:QI 2 "register_operand"                  "q")
-+  ))]
-+  ""
-+  "lea%0\t%2,%1\t;addhi_b: R:%0 = R:%2 + R:%1"
-+  [(set_attr "length" "*")])
-+
-+
-+; Splitter for addhi pattern #5 below
-+(define_split
-+  [(set (match_operand:HI 0 "index_register_operand" "")
-+    (plus:HI (match_dup 0) (match_operand:HI 1 "memory_operand" "")))]
-+  "reload_completed"
-+  [
-+   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
-+              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
-+   (set (reg:HI HARD_D_REGNUM)
-+        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 1)))
-+   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
-+              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
-+   ]
-+{
-+})
-+
-+
-+; Splitter for addhi pattern #7 below
-+(define_split
-+  [(set (match_operand:HI 0 "index_register_operand" "")
-+    (plus:HI (match_dup 0) (match_operand:HI 1 "index_register_operand" "")))]
-+  "reload_completed"
-+  [
-+   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
-+              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
-+   (set (match_dup 0)
-+        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 0)))
-+   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
-+              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
-+   ]
-+{
-+})
-+
-+
-+; TODO - this is ugly.  During RTL generation, we don't know what registers
-+; are available, so the multiple-insn sequences can only be solved
-+; via 'define_split's during matching.  See andhi3 for an example.
-+; Keep the constraints with ? modifiers to help reload pick the right
-+; registers.
-+;
-+; The forms are:
-+; 1. D += D, expand this into a shift instead. (rtx costs should be corrected
-+; to avoid this even happening...)
-+; 2. D += U, require U to be pushed to memory.  (Lots of patterns do this
-+; now, is this a better way?)
-+; 3. Best choice: 'addd'
-+; 4. Next best choice: 'lea'
-+; 5. Hybrid of 3 and 4
-+; 6. Same as 4, not bad
-+; 7. BAD, no D register at all
-+; 8. 'lea', as good as 4.
-+(define_insn "addhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"      "=d, d,  d,  a,?a, a,???T,a")
-+    (plus:HI(match_operand:HI 1 "add_general_operand"   "%0, 0,  0,  d, 0, a, 0, a")
-+    (match_operand:HI 2 "general_operand"               " 0, !U, mi, a, m, d, T, i")
-+  ))]
-+  ""
-+  "@
-+   lslb\t\t;addhi: R:%0 += R:%2\;rola\t\t;also R:%0 *= 2
-+   pshs\t%2\t;addhi: R:%0 += R:%2\;add%0\t,s++
-+   add%0\t%2
-+   lea%0\t%1,%2
-+   #
-+   lea%0\t%2,%1
-+   #
-+   lea%0\t%a2,%1"
-+   [(set_attr "length" "2,6,*,*,7,*,7,*")])
-+
-+
-+(define_insn "addqi3_carry"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
-+    (unspec:QI [
-+      (match_operand:QI 1 "whole_general_operand" "%0")
-+      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_ADD_CARRY))]
-+  ""
-+  "adc%0\t%2\t;addqi_carry: R:%0 += %2"
-+  [(set_attr "length" "*")])
-+
-+
-+; TODO: specifying 'A' for the first constraint, to force into the A register
-+; is not working because of the way registers are currently set up.  This will
-+; take some work to get right.  Thus the second alternative as a backup.
-+(define_insn "addqi3_decimal"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=A,?q")
-+    (unspec:QI [
-+      (match_operand:QI 1 "general_operand"        "%0,0")
-+      (match_operand:QI 2 "general_operand"        "tmi,tmi")] UNSPEC_ADD_DECIMAL))]
-+  ""
-+  "@
-+   adda\t%2\;daa
-+   tfr\t%0,a\;adda\t%2\;daa\;tfr\ta,%0"
-+  [(set_attr "length" "5,9")])
-+
-+
-+(define_insn "addqi3"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"       "=q,q,q,tm,tm,q")
-+    (plus:QI (match_operand:QI 1 "whole_general_operand" "%0,0,0,0,0,0")
-+    (match_operand:QI 2 "whole_general_operand"          " 0,I,N,I,N,tmi")))]
-+  ""
-+  "@
-+   asl%0\t\t;addqi: R:%0 = R:%0 + R:%0
-+   inc%0
-+   dec%0
-+   inc\t%0
-+   dec\t%0
-+   add%0\t%2"
-+  [(set_attr "length" "1,1,1,3,3,*")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Subtract instructions.
-+;;--------------------------------------------------------------------
-+
-+(define_insn "subsi3"
-+  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
-+     (minus:SI (match_operand:SI 1 "general_operand" " o")
-+        (match_operand:SI 2 "general_operand"       " oi")))
-+   (clobber (match_scratch:HI 3 "=d"))]
-+  ""
-+{
-+  m6809_output_addsi3 (MINUS, operands);
-+  return "";
-+}
-+  [(set_attr "length" "21")])
-+
-+
-+(define_insn "subhi3"
-+  [(set (match_operand:HI 0 "register_operand"      "=d,  d, a")
-+    (minus:HI (match_operand:HI 1 "register_operand" "0,  0, 0")
-+    (match_operand:HI 2 "general_operand"            "mi, ?U,n")))]
-+  ""
-+  "@
-+   sub%0\t%2\t;subhi: R:%0 -= %2
-+   pshs\t%2\t;subhi: R:%0 -= R:%2\;sub%0\t,s++
-+   lea%0\t%n2,%1\t;subhi: R:%0 = R:%1 + %n2"
-+   [(set_attr "length" "*,5,3")])
-+
-+
-+(define_insn "subqi3_carry"
-+  [(set (match_operand:QI 0 "register_operand" "=q")
-+    (unspec:QI [
-+      (match_operand:QI 1 "whole_general_operand" "%0")
-+      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_SUB_CARRY))]
-+  ""
-+  "sbc%0\t%2\t;subqi_carry: R:%0 += %2"
-+  [(set_attr "length" "*")])
-+
-+
-+(define_insn "subqi3"
-+  [(set (match_operand:QI 0 "register_operand"            "=q, q, !q, !q,   q")
-+    (minus:QI (match_operand:QI 1 "whole_register_operand" "0, 0,  I,  tmn, 0")
-+    (match_operand:QI 2 "whole_general_operand"            "I, mi, 0,  0,   t")))]
-+  ""
-+  "@
-+   dec%0
-+   sub%0\t%2
-+   dec%0\;neg%0
-+   sub%0\t%1\;neg%0
-+   sub%0\t%2"
-+   [(set_attr "length" "1,3,2,4,3")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Multiply instructions.
-+;;--------------------------------------------------------------------
-+
-+; TODO - merge these two instructions, using 'extend_operator' to match
-+; either signed or zero extension.  Everything else is the same.
-+(define_insn "mulqihi3"
-+   [(set (match_operand:HI 0 "register_operand" "=d")
-+      (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%q"))
-+      (match_operand:QI 2 "general_operand" "tmK")))]
-+  ""
-+  "lda\t%2\t;mulqihi3\;mul"
-+  [(set_attr "length" "3")])
-+
-+
-+(define_insn "umulqihi3"
-+   [(set (match_operand:HI 0 "register_operand" "=d")
-+    (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%q"))
-+    (match_operand:QI 2 "general_operand" "tmK")))]
-+  ""
-+  "lda\t%2\t;umulqihi3\;mul"
-+  [(set_attr "length" "3")])
-+
-+
-+; Expand a 16x16 multiplication into either a libcall or a shift.
-+; If the second operand is a small constant, use the above form.
-+; Otherwise, do a libcall.
-+(define_expand "mulhi3"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+    (mult:HI (match_operand:HI 1 "general_operand" "")
-+    (match_operand:HI 2 "nonmemory_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (HImode, "mulhi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Divide instructions.
-+;;--------------------------------------------------------------------
-+
-+(define_expand "divhi3"
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (div:HI (match_operand:HI 1 "register_operand" "")
-+    (match_operand:HI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (HImode, "divhi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+(define_expand "divqi3"
-+  [(set (match_operand:QI 0 "register_operand" "")
-+    (div:QI (match_operand:QI 1 "register_operand" "")
-+    (match_operand:QI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (QImode, "divqi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+(define_expand "udivhi3"
-+  [(set (match_operand:HI 0 "register_operand" "")
-+     (udiv:HI (match_operand:HI 1 "register_operand" "")
-+              (match_operand:HI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (HImode, "udivhi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+;;--------------------------------------------------------------------
-+;;- mod
-+;;--------------------------------------------------------------------
-+
-+(define_expand "modhi3"
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (mod:HI (match_operand:HI 1 "register_operand" "")
-+    (match_operand:HI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (HImode, "modhi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+(define_expand "modqi3"
-+  [(set (match_operand:QI 0 "register_operand" "")
-+    (mod:QI (match_operand:QI 1 "register_operand" "")
-+    (match_operand:QI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (QImode, "modqi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+(define_expand "umodhi3"
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (umod:HI (match_operand:HI 1 "register_operand" "")
-+    (match_operand:HI 2 "register_operand" "")))]
-+  ""
-+{
-+  emit_libcall_insns (HImode, "umodhi3", operands, 2);
-+  DONE;
-+})
-+
-+
-+
-+;;--------------------------------------------------------------------
-+;;- and, or, xor common patterns
-+;;--------------------------------------------------------------------
-+
-+; Split a bitwise HImode into two QImode instructions, with one of
-+; the sources in a pushable register.  The register is pushed onto
-+; the stack and memory pop operands (,s+) are used in the QI forms.
-+(define_split
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (match_operator:HI 3 "logical_bit_operator"
-+      [(match_operand:HI 1 "register_operand" "")
-+       (match_operand:HI 2 "register_operand" "")]))]
-+  "reload_completed"
-+  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 2))
-+   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
-+         [(reg:QI HARD_A_REGNUM)
-+          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
-+   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
-+         [(reg:QI HARD_D_REGNUM)
-+          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
-+   (use (reg:QI HARD_A_REGNUM))]
-+{
-+})
-+
-+; Split a bitwise HImode into two QImode instructions, with one
-+; of the sources being a (MEM (MEM (...)); i.e. an indirect memory
-+; reference.  This requires dereferencing the pointer into a
-+; temporary register (X), which must be saved/restored around the
-+; compute instructions.
-+(define_split 
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (match_operator:HI 3 "logical_bit_operator"
-+      [(match_operand:HI 1 "register_operand" "")
-+       (mem:HI (match_operand:HI 2 "memory_operand" ""))]))]
-+  "reload_completed"
-+  [
-+   (set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 4))
-+   (set (match_dup 4) (match_dup 2))
-+   (set (match_dup 4) (mem:HI (match_dup 4)))
-+   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
-+         [(reg:QI HARD_A_REGNUM)
-+          (mem:QI (post_inc:QI (match_dup 4)))]))
-+   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
-+         [(reg:QI HARD_D_REGNUM)
-+          (mem:QI (post_inc:QI (match_dup 4)))]))
-+   (use (reg:QI HARD_A_REGNUM))
-+   (set (match_dup 4) (mem:HI (post_inc:HI (reg:HI HARD_S_REGNUM))))
-+   ]
-+{
-+  /* Use X for a temporary index register */
-+  operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
-+})
-+
-+
-+; Split a bitwise HImode into two QImode instructions.  This is
-+; the common case.  This handles splitting when neither of the
-+; above two cases applies.
-+(define_split 
-+  [(set (match_operand:HI 0 "register_operand" "")
-+    (match_operator:HI 3 "logical_bit_operator"
-+      [(match_operand:HI 1 "register_operand" "")
-+       (match_operand:HI 2 "general_operand" "")]))]
-+  "reload_completed"
-+  [(set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
-+      [(reg:QI HARD_A_REGNUM) (match_dup 4)]))
-+   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
-+      [(reg:QI HARD_D_REGNUM) (match_dup 5)]))
-+   (use (reg:QI HARD_A_REGNUM))]
-+{
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+  {
-+    operands[4] = gen_rtx_const_high (operands[2]);
-+    operands[5] = gen_rtx_const_low (operands[2]);
-+  }
-+  else if ((GET_CODE (operands[2]) == MEM)
-+    && (GET_CODE (XEXP (operands[2], 0)) == MEM))
-+  {
-+    FAIL;
-+  }
-+  else
-+  {
-+    operands[4] = gen_highpart (QImode, operands[2]);
-+    operands[5] = gen_lowpart (QImode, operands[2]);
-+  }
-+})
-+
-+; Below are the specific cases for each of the operators.
-+; The QImode versions are the simplest and can be implemented
-+; directly on the hardware.  The HImode cases are all output
-+; using one of the above splitting techniques.
-+
-+;;--------------------------------------------------------------------
-+;;- and
-+;;--------------------------------------------------------------------
-+
-+(define_insn "andhi3"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+    (and:HI (match_operand:HI 1 "register_operand" "%0")
-+    (match_operand:HI 2 "general_operand" "mnU")))]
-+  ""
-+  "#")
-+
-+;; it is not clear that this is correct
-+(define_insn "*andqi_2"
-+  [(set
-+   (match_operand:QI 0 "register_operand" "=q")
-+   (and:QI (match_operand:QI 1 "register_operand" "q")
-+     (match_operand 2 "const_int_operand" "i")))]
-+  ""
-+{
-+  if (GET_CODE (operands[2]) == CONST_INT)
-+  {
-+    operands[3] = GEN_INT(INTVAL(operands[2]) & 0xff);
-+    return "and%0 %3";
-+  }
-+
-+  return "and%0 %2";
-+}
-+  [(set_attr "length" "2")])
-+
-+(define_insn "andqi3"
-+  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,qc")
-+    (and:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
-+    (match_operand:QI 2 "whole_general_operand"          " O,N,tm,i")))]
-+  ""
-+  "@
-+   clr%0\t;andqi(ZERO)
-+   \t;andqi(-1)
-+   and%0\t%2
-+   and%0\t%2"
-+   [(set_attr "length" "1,0,3,2")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- or
-+;;--------------------------------------------------------------------
-+
-+(define_insn "iorhi3"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+    (ior:HI (match_operand:HI 1 "register_operand" "%0")
-+    (match_operand:HI 2 "general_operand" "mnU")))]
-+  ""
-+  "#")
-+
-+
-+(define_insn "iorqi3"
-+  [(set (match_operand:QI 0 "register_operand"           "=q,q, qc")
-+    (ior:QI (match_operand:QI 1 "whole_register_operand" "%0,0, 0")
-+    (match_operand:QI 2 "whole_general_operand"          " O,tm,i")))]
-+  ""
-+  "@
-+   \t;iorqi(ZERO)
-+   or%0\t%2
-+   or%0\t%2"
-+   [(set_attr "length" "0,3,2")])
-+
-+;;--------------------------------------------------------------------
-+;;- xor
-+;;--------------------------------------------------------------------
-+
-+(define_insn "xorhi3"
-+  [(set (match_operand:HI 0 "register_operand" "=d")
-+    (xor:HI (match_operand:HI 1 "register_operand" "%0")
-+    (match_operand:HI 2 "general_operand" "mnU")))]
-+  ""
-+  "#")
-+
-+
-+(define_insn "xorqi3"
-+  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,q")
-+    (xor:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
-+    (match_operand:QI 2 "whole_general_operand"          " O,N,tm,i")))]
-+  ""
-+  "@
-+   \t;xorqi(ZERO)
-+   com%0\t;xorqi(-1)
-+   eor%0\t%2
-+   eor%0\t%2"
-+   [(set_attr "length" "0,1,3,2")])
-+
-+;;--------------------------------------------------------------------
-+;;-  Two's Complements
-+;;--------------------------------------------------------------------
-+
-+(define_insn "neghi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!a")
-+    (neg:HI (match_operand:HI 1 "general_operand"   "0, 0")))]
-+  ""
-+  "@
-+   nega\;negb\;sbca\t#0
-+   exg\td,%0\;nega\;negb\;sbca\t#0\;exg\td,%0"
-+  [(set_attr "length" "5,9")])
-+
-+
-+(define_insn "negqi2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
-+    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
-+  ""
-+  "@
-+   neg%0
-+   neg\t%0"
-+  [(set_attr "length" "1,3")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  One's Complements
-+;;--------------------------------------------------------------------
-+
-+(define_insn "one_cmplhi2"
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,?tm,???a")
-+    (not:HI (match_operand:HI 1 "general_operand"   "0,  0,   0")))]
-+  ""
-+  "@
-+   coma\;comb
-+   com\t%0\;com\t%L0
-+   exg\td,%0\;coma\;comb\;exg\td,%0"
-+  [(set_attr "length" "2,6,6")])
-+
-+
-+(define_insn "one_cmplqi2"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,tm")
-+    (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
-+  ""
-+  "@
-+   com%0
-+   com\t%0"
-+  [(set_attr "length" "1,3")])
-+
-+;;--------------------------------------------------------------------
-+;;- Shifts/rotates
-+;;--------------------------------------------------------------------
-+
-+(define_code_iterator bit_code [ashift ashiftrt lshiftrt])
-+(define_code_attr bit_code_name [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
-+
-+(define_mode_iterator bit_mode [QI HI])
-+(define_mode_attr bit_mode_name [(QI "qi3") (HI "hi3")])
-+
-+;; Emit RTL for any shift (handles all 3 opcodes and 2 mode sizes)
-+
-+(define_expand "<bit_code:bit_code_name><bit_mode:bit_mode_name>"
-+  [(set (match_operand:bit_mode 0 "nonimmediate_operand" "")
-+    (bit_code:bit_mode (match_operand:bit_mode 1 "general_operand" "")
-+    (match_operand:bit_mode 2 "nonmemory_operand" "")))]
-+  ""
-+{
-+})
-+
-+; Individual instructions implemented in the CPU.
-+
-+
-+(define_insn "*ashift1"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
-+    (ashift:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
-+  ""
-+  "@
-+   asl\t%0
-+   asl%0"
-+  [(set_attr "length" "3,1")])
-+
-+(define_insn "*lshiftrt1"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
-+    (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
-+  ""
-+  "@
-+   lsr\t%0
-+   lsr%0"
-+  [(set_attr "length" "3,1")])
-+
-+(define_insn "*ashiftrt1"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
-+    (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
-+  ""
-+  "@
-+   asr\t%0
-+   asr%0"
-+  [(set_attr "length" "3,1")])
-+
-+(define_insn "*rotate1"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
-+    (rotate:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
-+  ""
-+  "@
-+   rol\t%0
-+   rol%0"
-+  [(set_attr "length" "3,1")])
-+
-+
-+(define_insn "*rotatert1"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
-+    (rotatert:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
-+  ""
-+  "@
-+   ror\t%0
-+   ror%0"
-+  [(set_attr "length" "3,1")])
-+
-+
-+; A shift by 8 for D reg can be optimized by just moving
-+; between the A/B halves, and then zero/sign extending or
-+; filling in zeroes.
-+; Because GCC does not understand that 'A' and 'D' refer to
-+; the same storage location, we must use 'USE' throughout
-+; to prevent deletion of 'unnecessary' instructions.
-+; Similar optimization for MEM would require a scratch register
-+; so is not done here.
-+
-+(define_split
-+  [(set (reg:HI HARD_D_REGNUM) (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
-+  "reload_completed"
-+  [
-+   (use (reg:HI HARD_D_REGNUM))
-+   (set (reg:QI HARD_A_REGNUM) (reg:QI HARD_D_REGNUM))
-+   (use (reg:QI HARD_A_REGNUM))
-+   (set (reg:QI HARD_D_REGNUM) (const_int 0))
-+   ]
-+  "")
-+
-+(define_split
-+  [(set (reg:HI HARD_D_REGNUM) (lshiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
-+  "reload_completed"
-+  [
-+   (use (reg:HI HARD_D_REGNUM))
-+   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
-+   (use (reg:QI HARD_D_REGNUM))
-+   (set (reg:HI HARD_D_REGNUM) (zero_extend:HI (reg:QI HARD_D_REGNUM)))
-+   ]
-+  "")
-+
-+(define_split
-+  [(set (reg:HI HARD_D_REGNUM) (ashiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
-+  "reload_completed"
-+  [
-+   (use (reg:HI HARD_D_REGNUM))
-+   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
-+   (use (reg:QI HARD_D_REGNUM))
-+   (set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
-+   ]
-+  "")
-+
-+
-+; On the WPC hardware, there is a shift register that can be used
-+; to compute (1<<n) efficiently in two instructions.  Note that this
-+; form only works when using -mint8 though, because C will promote
-+; to 'int' when doing this operation.  TODO : we need a 16-bit form too.
-+(define_insn "ashlqi3_wpc"
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
-+    (ashift:QI (match_operand:QI 1 "immediate_operand" "I")
-+    (match_operand:QI 2 "general_operand" "q")))]
-+  "TARGET_WPC"
-+  "st%2\t0x3FF7\;ld%0\t0x3FF7"
-+  [(set_attr "length" "6")])
-+
-+
-+; Internal instructions for shifting by a constant.
-+; Two forms are provided, one for QImode, one for HImode.
-+; These are always split into the above instructions
-+; (except for QImode forms that directly match one of the
-+; above instructions, in which the condition will not
-+; allow the splitter to match).
-+
-+(define_insn_and_split "<bit_code:bit_code_name>hi3_const"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"     "=dm")
-+    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
-+    (match_operand:HI 2 "immediate_operand"            "n")))]
-+  ""
-+  "#"
-+  "reload_completed"
-+  [(const_int 0)]
-+{
-+  m6809_split_shift (<bit_code:CODE>, operands);
-+  DONE;
-+})
-+
-+
-+(define_insn_and_split "<bit_code:bit_code_name>qi3_const"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"     "=qm")
-+    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
-+    (match_operand:QI 2 "immediate_operand"            "n")))]
-+  "INTVAL (operands[2]) > 1"
-+  "#"
-+  "&& reload_completed"
-+  [(const_int 0)]
-+{
-+  m6809_split_shift (<bit_code:CODE>, operands);
-+  DONE;
-+})
-+
-+; Internal instructions for shifting by a nonconstant.
-+; These expand into complex assembly.
-+
-+(define_insn "<bit_code:bit_code_name>hi3_reg"
-+  [(set (match_operand:HI 0 "nonimmediate_operand"     "=d")
-+    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
-+    (match_operand:HI 2 "nonimmediate_operand"         "v")))]
-+  ""
-+{
-+  m6809_output_shift_insn (<bit_code:CODE>, operands);
-+  return "";
-+}
-+  [(set_attr "length" "20")])
-+
-+
-+(define_insn "<bit_code:bit_code_name>qi3_reg"
-+  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q")
-+    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
-+    (match_operand:QI 2 "nonimmediate_operand"         "v")))]
-+  ""
-+{
-+  m6809_output_shift_insn (<bit_code:CODE>, operands);
-+  return "";
-+}
-+  [(set_attr "length" "16")])
-+
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Jumps and transfers
-+;;--------------------------------------------------------------------
-+
-+;;; The casesi pattern is normally *not* defined; see 'tablejump' instead.
-+(define_expand "casesi"
-+  [(match_operand:HI 0 "register_operand" "")   ; index to jump on
-+   (match_operand:HI 1 "immediate_operand" "")   ; lower bound
-+   (match_operand:HI 2 "immediate_operand" "")   ; total range
-+   (match_operand 3 "" "")   ; table label
-+   (match_operand 4 "" "")]  ; out of range label
-+  "TARGET_BYTE_INT && TARGET_CASESI"
-+{
-+  m6809_do_casesi (operands[0], operands[1], operands[2],
-+                   operands[3], operands[4]);
-+  DONE;
-+})
-+
-+(define_insn "tablejump_short_offset"
-+  [(set (pc)
-+       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
-+                (zero_extend:HI (match_operand:QI 0 "register_operand" "q")))))]
-+  ""
-+  "jmp\t[b,x]\t;tablejump_short_offset"
-+  [(set_attr "length" "3")])
-+
-+(define_insn "tablejump_long_offset"
-+  [(set (pc)
-+       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
-+                (match_operand:HI 0 "register_operand" "d"))))]
-+  ""
-+  "jmp\t[d,x]\t;tablejump_long_offset"
-+  [(set_attr "length" "3")])
-+
-+
-+ ;; A tablejump operation gives the address in operand 0, with the
-+ ;; CODE_LABEL for the table in operand 1.  The 'define_expand'
-+ ;; shows the arguments as GCC presents them.  For a register
-+ ;; operand, the assembly code is straightforward.  For a MEM,
-+ ;; assumed to be a SYMBOL_REF, two forms are given, one normal
-+ ;; and one for PIC mode.
-+ (define_expand "tablejump"
-+    [(parallel [
-+     (set (pc) (match_operand:HI 0 "" ""))
-+     (use (label_ref (match_operand 1 "" "")))
-+     (clobber (match_scratch:HI 2 ""))
-+     ])]
-+    ""
-+ {
-+ })
-+
-+
-+(define_insn "*tablejump_reg"
-+   [(parallel [
-+      (set (pc)
-+         (match_operand:HI 0 "register_operand" "a"))
-+      (use (label_ref (match_operand 1 "" "")))
-+      (clobber (match_scratch:HI 2 ""))
-+      ])]
-+   ""
-+   "jmp\t,%0"
-+   [(set_attr "length" "3")])
-+
-+
-+(define_insn "*tablejump_symbol"
-+  [(parallel [
-+     (set (pc)
-+        (mem:HI
-+           (plus:HI (match_operand:HI 0 "register_operand" "a")
-+                    (label_ref (match_operand 1 "" "")))))
-+     (use (label_ref (match_dup 1)))
-+     (clobber (match_scratch:HI 2 ""))
-+     ])]
-+  "!flag_pic"
-+{
-+  output_asm_insn ("jmp\t[%a1,%0]", operands);
-+  return "";
-+}
-+  [(set_attr "length" "4")])
-+
-+
-+(define_insn "*tablejump_symbol_pic"
-+  [(parallel [
-+     (set (pc)
-+        (mem:HI
-+           (plus:HI (match_operand:HI 0 "register_operand" "d")
-+                    (label_ref (match_operand 1 "" "")))))
-+     (use (label_ref (match_dup 1)))
-+     (clobber (match_scratch:HI 2 "=&a"))
-+     ])]
-+  "flag_pic"
-+{
-+  output_asm_insn ("lea%2\t%a1,pcr", operands);
-+  output_asm_insn ("ld%0\t%0,%2", operands);
-+  output_asm_insn ("jmp\t%0,%2", operands);
-+  return "";
-+}
-+  [(set_attr "length" "8")])
-+
-+
-+(define_insn "indirect_jump"
-+  [(set (pc)
-+    (match_operand:HI 0 "register_operand" "a"))]
-+  ""
-+  "jmp\t,%0"
-+  [(set_attr "length" "3")])
-+
-+
-+(define_insn "jump"
-+  [(set (pc) (label_ref (match_operand 0 "" "")))]
-+  ""
-+{
-+  return output_branch_insn ( LABEL_REF, operands, get_attr_length (insn));
-+}
-+  [(set (attr "type") (const_string "branch"))])
-+
-+; Output assembly for a condition branch instruction.
-+(define_insn "*cond_branch"
-+  [(set (pc)
-+    (if_then_else
-+      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
-+        (label_ref (match_operand 0 "" "")) (pc)))]
-+  ""
-+{
-+  return output_branch_insn ( GET_CODE(operands[1]),
-+    operands, get_attr_length (insn));
-+}
-+  [(set (attr "type") (const_string "cbranch"))])
-+
-+
-+; Similar to above, but for a condition branch instruction that
-+; had its operands reversed at some point.
-+(define_insn "*cond_branch_reverse"
-+  [(set (pc)
-+    (if_then_else
-+      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
-+      (pc) (label_ref (match_operand 0 "" ""))))]
-+  ""
-+{
-+  return output_branch_insn ( reverse_condition (GET_CODE(operands[1])),
-+    operands, get_attr_length (insn));
-+}
-+  [(set (attr "type") (const_string "cbranch"))])
-+
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Calls
-+;;--------------------------------------------------------------------
-+
-+;; Generate a call instruction for a function that does not
-+;; return a value.  The expander is used during RTL generation.
-+;; The instructions below are used during matching; only one
-+;; of them will be used, depending on the type of function
-+;; being called.  The different conditions are:
-+;;
-+;;    1) far_functionp - is this a far function?  Those need
-+;;    to be output as indirect calls through a far-function
-+;;    handler.
-+;;
-+;;    2) noreturn_functionp - if the function does not return,
-+;;    we can use a 'jmp' instead of a 'jsr' to call it.
-+;;
-+;;    3) is PIC mode enabled?  If so, we'll always use
-+;;    relative calls (lbsr or lbra).
-+;;
-+;; Note: not all combinations are fully supported, especially
-+;; relating to PIC.
-+;;
-+;; The 'bsr' instruction is never generated.
-+
-+(define_expand "call"
-+  [(call (match_operand:HI 0 "memory_operand" "")
-+    (match_operand:HI 1 "general_operand" ""))]
-+  ""
-+  "")
-+
-+(define_insn "*call_nopic_far"
-+  [(call (match_operand:HI 0 "memory_operand" "m")
-+    (match_operand:HI 1 "general_operand" "g"))]
-+  "far_functionp (operands[0])"
-+{
-+  output_far_call_insn (operands, 0);
-+  return "";
-+}
-+  [(set_attr "length" "6")])
-+
-+
-+; PIC forms come first, and should only match
-+; (MEM (SYMBOL_REF)).  Other MEM forms are treated as usual.
-+(define_insn "*call_pic"
-+  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
-+    (match_operand:HI 1 "general_operand" "g"))]
-+  "flag_pic && !noreturn_functionp (operands[0])"
-+  "lbsr\t%C0"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_insn "*call_nopic"
-+  [(call (match_operand:HI 0 "memory_operand" "m")
-+    (match_operand:HI 1 "general_operand" "g"))]
-+  "!noreturn_functionp (operands[0])"
-+  "jsr\t%0"
-+  [(set_attr "length" "3")
-+   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
-+
-+
-+(define_insn "*call_noreturn_pic"
-+  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
-+    (match_operand:HI 1 "general_operand" "g"))]
-+  "flag_pic && noreturn_functionp (operands[0])"
-+  "lbra\t%C0"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_insn "*call_noreturn_nopic"
-+  [(call (match_operand:HI 0 "memory_operand" "m")
-+    (match_operand:HI 1 "general_operand" "g"))]
-+  "noreturn_functionp (operands[0])"
-+  "jmp\t%0"
-+  [(set_attr "length" "3")])
-+
-+
-+;;
-+;; Same as above, but for functions that do return a value.
-+;;
-+(define_expand "call_value"
-+  [(set (match_operand 0 "" "")
-+    (call (match_operand:HI 1 "memory_operand" "")
-+    (match_operand:HI 2 "general_operand" "")))]
-+  ""
-+  "")
-+
-+
-+(define_insn "*call_value_far"
-+  [(set (match_operand 0 "" "=gz")
-+    (call (match_operand:HI 1 "memory_operand" "m")
-+    (match_operand:HI 2 "general_operand" "g")))]
-+  "far_functionp (operands[1])"
-+{
-+  output_far_call_insn (operands, 1);
-+  return "";
-+}
-+  [(set_attr "length" "6")])
-+
-+
-+(define_insn "*call_value_pic"
-+  [(set (match_operand 0 "" "=gz")
-+    (call (mem:HI (match_operand:HI 1 "symbolic_operand" ""))
-+    (match_operand:HI 2 "general_operand" "g")))]
-+  "flag_pic"
-+  "lbsr\t%C1"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_insn "*call_value_nopic"
-+  [(set (match_operand 0 "" "=gz")
-+    (call (match_operand:HI 1 "memory_operand" "m")
-+    (match_operand:HI 2 "general_operand" "g")))]
-+  ""
-+  "jsr\t%1"
-+  [(set_attr "length" "3")
-+   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
-+
-+
-+
-+;;
-+;; How to generate an untyped call.
-+;;
-+(define_expand "untyped_call"
-+  [(parallel [(call (match_operand 0 "" "")
-+        (const_int 0))
-+      (match_operand 1 "" "")
-+      (match_operand 2 "" "")])]
-+  ""
-+{
-+  int i;
-+
-+  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
-+  for (i=0; i < XVECLEN (operands[2], 0); i++)
-+  {
-+    rtx set = XVECEXP (operands[2], 0, i);
-+    emit_move_insn (SET_DEST (set), SET_SRC (set));
-+  }
-+  emit_insn (gen_blockage ());
-+  DONE;
-+})
-+
-+
-+(define_expand "sibcall"
-+  [(parallel
-+     [(call (match_operand:HI 0 "memory_operand" "")
-+            (match_operand:HI 1 "immediate_operand" ""))
-+      (use (reg:HI HARD_PC_REGNUM))])]
-+  ""
-+  "")
-+
-+(define_insn "*sibcall_1"
-+  [(parallel
-+     [(call (match_operand:HI 0 "memory_operand" "m")
-+            (match_operand:HI 1 "immediate_operand" "i"))
-+      (use (reg:HI HARD_PC_REGNUM))])]
-+  "SIBLING_CALL_P(insn)"
-+  "jmp\t%0"
-+  [(set_attr "length" "4")])
-+
-+
-+(define_expand "sibcall_value"
-+  [(parallel
-+     [(set (match_operand 0 "" "")
-+         (call (match_operand:HI 1 "memory_operand" "")
-+               (match_operand:HI 2 "immediate_operand" "")))
-+      (use (reg:HI HARD_PC_REGNUM))])]
-+  ""
-+  "")
-+
-+(define_insn "*sibcall_value_1"
-+  [(parallel
-+     [(set (match_operand 0 "" "=gz")
-+         (call (match_operand:HI 1 "memory_operand" "m")
-+               (match_operand:HI 2 "immediate_operand" "i")))
-+      (use (reg:HI HARD_PC_REGNUM))])]
-+  "SIBLING_CALL_P(insn)"
-+  "jmp\t%1"
-+  [(set_attr "length" "4")])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Function Entry and Exit
-+;;--------------------------------------------------------------------
-+
-+;; On entry to a function, the stack frame looks as follows:
-+;; - return address (pushed by the caller)
-+;; - saved registers
-+;; - local variable storage
-+;;
-+;; If the function does not modify the stack after that, then
-+;; any of these can be accessed directly as an offset from
-+;; STACK_POINTER_REGNUM.  Otherwise, a frame pointer is required.
-+;; In that case, the prologue must also initialize HARD_FRAME_POINTER_REGNUM
-+;; and all references to the stack frame will use that as a base instead.
-+;;
-+(define_expand "prologue"
-+  [(const_int 0)]
-+  "prologue_epilogue_required ()"
-+{
-+  emit_prologue_insns ();
-+  DONE;
-+})
-+
-+
-+;; The function epilogue does exactly the reverse of the prologue,
-+;; deallocating local variable space, restoring saved registers,
-+;; and returning.
-+;;
-+;; For the 6809, the return may be 'rti' if the function was
-+;; declared as an interrupt function, but is normally 'rts'.
-+;;
-+;; Also, as an optimization, the register restore and the 'rts'
-+;; can be combined into a single instruction, by adding 'PC' to the
-+;; list of registers to be restored.  This is only done if there are
-+;; any saved registers, as 'rts' is more efficient by itself.
-+;;
-+(define_expand "epilogue"
-+  [(const_int 0)]
-+  "prologue_epilogue_required ()"
-+{
-+  emit_epilogue_insns (false);
-+  DONE;
-+})
-+
-+
-+(define_expand "sibcall_epilogue"
-+  [(const_int 0)]
-+  "prologue_epilogue_required ()"
-+{
-+  emit_epilogue_insns (true);
-+  DONE;
-+})
-+
-+
-+;; The RTS instruction
-+(define_insn "return_rts"
-+  [(return)
-+   (use (reg:HI HARD_PC_REGNUM))]
-+  "!m6809_current_function_has_type_attr_p (\"interrupt\")
-+   && m6809_get_live_regs () == 0"
-+  "rts"
-+  [(set_attr "length" "1")
-+   (set (attr "cycles") (const_int RTS_CYCLES))])
-+
-+(define_insn "return_puls_pc"
-+  [(return)
-+   (use (reg:HI HARD_PC_REGNUM))]
-+  "!m6809_current_function_has_type_attr_p (\"interrupt\")
-+   && m6809_get_live_regs () != 0"
-+  ""
-+  [(set_attr "length" "1")
-+   (set (attr "cycles") (const_int RTS_CYCLES))])
-+
-+;; The RTI instruction
-+(define_insn "return_rti"
-+  [(return)
-+   (use (reg:HI HARD_PC_REGNUM))]
-+  "m6809_current_function_has_type_attr_p (\"interrupt\")"
-+  "rti"
-+  [(set_attr "length" "1")
-+   (set (attr "cycles") (const_int RTI_CYCLES))])
-+
-+
-+;;--------------------------------------------------------------------
-+;;-  Unspecified instructions
-+;;--------------------------------------------------------------------
-+
-+;; An instruction that has the effect of an unspec_volatile, but
-+;; which doesn't require emitting any assembly code.
-+(define_insn "blockage"
-+  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
-+  ""
-+  ""
-+  [(set_attr "length" "0")
-+   (set (attr "cycles") (const_int 0))])
-+
-+
-+;; Say how to push multiple registers onto the stack, using
-+;; the 6809 'pshs' instruction.  The operand is a regset
-+;; specifying which registers to push.
-+;;
-+;; The operand mode is not given intentionally, so as to allow
-+;; any possible integer mode for the regset.
-+;;
-+;; See below for a peephole that can combine consecutive push
-+;; instructions that qualify for merging.
-+(define_insn "register_push"
-+  [(use (reg:HI HARD_S_REGNUM))
-+    (unspec_volatile
-+      [(match_operand 0 "immediate_operand" "")] UNSPEC_PUSH_RS)
-+    (clobber (reg:HI HARD_S_REGNUM))]
-+  ""
-+  "pshs\t%R0"
-+  [(set_attr "length" "2")
-+   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
-+
-+
-+;; Say how to pop multiple registers from the stack, using
-+;; the 6809 'puls' instruction.  The operand is the register
-+;; bitset value.
-+(define_insn "register_pop"
-+  [(use (reg:HI HARD_S_REGNUM))
-+    (unspec_volatile
-+      [(match_operand 0 "immediate_operand" "")] UNSPEC_POP_RS)
-+    (clobber (reg:HI HARD_S_REGNUM))]
-+  ""
-+  "puls\t%R0"
-+  [(set_attr "length" "2")
-+   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
-+
-+
-+(define_insn "m6809_swi"
-+  [(unspec_volatile
-+    [(match_operand:QI 0 "immediate_operand" "I,n")] UNSPEC_SWI)]
-+  ""
-+  "@
-+   swi
-+   swi%c0"
-+  [(set_attr "length" "1,2")
-+   (set (attr "cycles") (const_int SWI_CYCLES))])
-+
-+
-+;; Generate the CWAI instruction
-+(define_insn "m6809_cwai"
-+  [(unspec_volatile
-+    [(match_operand:QI 0 "immediate_operand" "")] UNSPEC_CWAI)]
-+  ""
-+  "cwai\t%0"
-+  [(set_attr "length" "2")
-+   (set (attr "cycles") (const_int CWAI_CYCLES))])
-+
-+
-+;; Generate the SYNC instruction
-+(define_insn "m6809_sync"
-+  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
-+  ""
-+  "sync"
-+  [(set_attr "length" "1")
-+   (set (attr "cycles") (const_int SYNC_CYCLES))])
-+
-+
-+;; Generate the NOP instruction
-+(define_insn "nop"
-+  [(const_int 0)]
-+  ""
-+  "nop"
-+   [(set_attr "length" "1")
-+   (set (attr "cycles") (const_int NOP_CYCLES))])
-+
-+
-+;;--------------------------------------------------------------------
-+;;- Peepholes
-+;;--------------------------------------------------------------------
-+
-+;;; Each peephole has an ID that is used for debugging.
-+;;; Each peephole condition is bracketed by calls to
-+;;; m6809_match_peephole2() also for debugging.
-+(define_constants [
-+  (PEEP_END 0)
-+  (PEEP_COND 1)
-+
-+  (PEEP_STACK_STORE_INC 0)
-+  (PEEP_STACK_CLEAR_INC 1)
-+  (PEEP_LSRB_ADCB 2)
-+  (PEEP_ABX 3)
-+  (PEEP_ABX2 4)
-+  (PEEP_INDEXED_INC 5)
-+  (PEEP_MEM_DEC 6)
-+  (PEEP_MEM_INC 7)
-+  (PEEP_MEM_DEC_CMP 8)
-+  (PEEP_PUSH2 9)
-+  (PEEP_STORE_IMPLIES_CC 10)
-+  (PEEP_DEC_IMPLIES_CC 11)
-+  (PEEP_LEAB 12)
-+  (PEEP_LDX_INDIRECT 13)
-+  (PEEP_POP_JUNK 14)
-+])
-+
-+
-+;;; Optimize 'leas -1,s' followed by 'stb ,s'.  This can happen if the
-+;;; function prologue needs to allocate stack space and 'b' is placed
-+;;; into that local right away.  Combine the stack allocation with the
-+;;; store using preincrement mode.
-+(define_peephole2
-+  [(set (reg:HI HARD_S_REGNUM)
-+        (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
-+   (set (mem:QI (reg:HI HARD_S_REGNUM))
-+        (match_operand:QI 0 "register_operand" ""))]
-+  "m6809_match_peephole2 (PEEP_STACK_STORE_INC, PEEP_END)"
-+  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 0))]
-+  "")
-+
-+
-+;;; Same as above, but for a 'clr ,s' that follows the prologue.
-+(define_peephole2
-+  [(set (reg:HI HARD_S_REGNUM) (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
-+   (set (mem:QI (reg:HI HARD_S_REGNUM)) (const_int 0))]
-+  "m6809_match_peephole2 (PEEP_STACK_CLEAR_INC, PEEP_END)"
-+  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (const_int 0))]
-+  "")
-+
-+
-+;;; Merge two consecutive push instructions into a single register_push.
-+(define_peephole2
-+  [(set (match_operand 0 "push_operand" "")
-+    (match_operand 1 "register_operand" ""))
-+   (set (match_operand 2 "push_operand" "")
-+    (match_operand 3 "register_operand" ""))]
-+  "m6809_match_peephole2 (PEEP_PUSH2, PEEP_COND)
-+   && reload_completed
-+   && GET_MODE (operands[1]) == GET_MODE (operands[3])
-+   && m6809_can_merge_pushpop_p (UNSPEC_PUSH_RS, 1 << REGNO (operands[1]), 1 << REGNO (operands[3]))
-+   && m6809_match_peephole2 (PEEP_PUSH2, PEEP_END)"
-+  [(parallel [
-+    (use (reg:HI HARD_S_REGNUM))
-+    (unspec_volatile [(match_dup 4)] UNSPEC_PUSH_RS)
-+    (clobber (reg:HI HARD_S_REGNUM))])
-+   (use (match_dup 1))
-+   (use (match_dup 3))]
-+{
-+  operands[4] = gen_rtx_CONST_INT (QImode,
-+    (1 << REGNO (operands[1])) | (1 << REGNO (operands[3])));
-+})
-+
-+
-+;;; Convert 'stX ,--s' into a push instruction.  Use the regset
-+;;; notation, so that it may be combined with an adjacent regset.
-+;;; TBD - this doesn't compile some code cleanly.
-+;(define_peephole2
-+;  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM)))
-+;        (reg:HI HARD_X_REGNUM))]
-+;  "reload_completed"
-+;  [(parallel [
-+;    (use (reg:HI HARD_S_REGNUM))
-+;    (unspec_volatile [(match_dup 0)] UNSPEC_PUSH_RS)
-+;    (clobber (reg:HI HARD_S_REGNUM))])]
-+;{
-+;  operands[0] = gen_rtx_CONST_INT (HImode, X_REGBIT);
-+;})
-+
-+
-+;;;
-+;;; q = (q+1)/2 can be optimized as "lsrb; adcb".  This also
-+;;; won't overflow when q=0xFF.
-+;;; TODO : this form isn't accounting for promotion when
-+;;; using 16-bit ints.
-+;;;
-+(define_peephole
-+  [(set (reg:QI HARD_D_REGNUM)
-+    (lshiftrt:QI (plus:HI (match_dup 0) (const_int 1)) (const_int 1)))]
-+  "m6809_match_peephole2 (PEEP_LSRB_ADCB, PEEP_END)"
-+  "lsrb\;adcb\t#0; peephole"
-+  [(set_attr "length" "2")])
-+
-+
-+;;
-+;; Optimize the case of following a register store with a test
-+;; of reg or mem just moved.
-+;;
-+(define_peephole
-+  [(set (match_operand:HI 0 "memory_operand" "=m")
-+  (match_operand:HI 1 "register_operand" "r"))
-+   (set (cc0) (match_operand:HI 2 "general_operand" "g"))]
-+  "m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_COND)
-+   && (operands[2] == operands[0] || operands[2] == operands[1])
-+   && m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_END)"
-+  "st%1\t%0\t;movhi: R:%1 -> %0 w/ implied test of %2"
-+  [(set_attr "length" "4")])
-+
-+
-+;; Optimize a pair of SET instructions in which the second insn
-+;; is the reverse of the first one.  I.e.
-+;;
-+;; A = B
-+;;        ---->  A = B
-+;; B = A
-+;;
-+;; The second insn is redundant.  Define two patterns, one for QI, one for HI.
-+;; But don't do this if either is a VOLATILE MEM.
-+(define_peephole2
-+  [(set (match_operand:HI 0 "nonimmediate_operand" "")
-+        (match_operand:HI 1 "nonimmediate_operand" ""))
-+  (set (match_dup 1) (match_dup 0))]
-+  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
-+  [(set (match_dup 0) (match_dup 1))]
-+  "")
-+
-+(define_peephole2
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+        (match_operand:QI 1 "nonimmediate_operand" ""))
-+  (set (match_dup 1) (match_dup 0))]
-+  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
-+  [(set (match_dup 0) (match_dup 1))]
-+  "")
-+
-+
-+;;
-+;; Optimize the sum of an 8-bit and 16-bit using the 'abx' instruction
-+;; if B and X can be used.  Two patterns are provided to catch both
-+;; X=X+D and X=D+X.
-+;;
-+(define_peephole
-+  [(set (reg:HI HARD_D_REGNUM)
-+    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
-+   (set (reg:HI HARD_X_REGNUM)
-+    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
-+  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
-+  "abx"
-+  [(set_attr "length" "1")])
-+
-+(define_peephole
-+  [(set (reg:HI HARD_D_REGNUM)
-+    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
-+   (set (reg:HI HARD_X_REGNUM)
-+    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
-+  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
-+  "abx"
-+  [(set_attr "length" "1")])
-+
-+;;; Likewise, handle when B is scaled by 2 prior to the add.
-+;;; Instead of shifting B in 4 cycles, just do the ABX a second
-+;;; time, in only 3 cycles.
-+
-+(define_peephole
-+  [(set (reg:HI HARD_D_REGNUM)
-+    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
-+   (set (reg:HI HARD_D_REGNUM)
-+    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
-+   (set (reg:HI HARD_X_REGNUM)
-+    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
-+  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
-+  "abx\;abx"
-+  [(set_attr "length" "2")])
-+
-+(define_peephole
-+  [(set (reg:HI HARD_D_REGNUM)
-+    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
-+   (set (reg:HI HARD_D_REGNUM)
-+    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
-+   (set (reg:HI HARD_X_REGNUM)
-+    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
-+  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
-+  "abx\;abx"
-+  [(set_attr "length" "2")])
-+
-+
-+;;
-+;; Work around a compiler bug that generates bad code when copying
-+;; between 32-bit memory addresses after a libcall.  The problem seen is
-+;; that the source is MEM (REG X), but X is used as the reload register.
-+;; The second half of the copy therefore fails.
-+;;
-+;; The solution is to switch the reload register to D, since that is guaranteed
-+;; not to be in use right after a libcall.
-+;;
-+(define_peephole2
-+  [(set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
-+   (set (match_operand:HI 0 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))
-+   (set (reg:HI HARD_X_REGNUM)
-+      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
-+   (set (match_operand:HI 1 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))]
-+  "reload_completed"
-+  [(set (reg:HI HARD_D_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
-+   (set (match_dup 0) (reg:HI HARD_D_REGNUM))
-+   (set (reg:HI HARD_X_REGNUM)
-+      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
-+   (set (match_dup 1) (reg:HI HARD_X_REGNUM))]
-+  "")
-+
-+
-+;; Turn "and then test" into a "bit test" operation.
-+;; Provide variants for immediate and memory sources
-+;; This is the most used peephople.
-+; (define_peephole
-+;   [(set (match_operand:QI 0 "register_operand" "=q")
-+;     (and:QI (match_operand:QI 1 "register_operand" "0")
-+;       (match_operand:QI 2 "immediate_operand" "i")))
-+;    (set (cc0) (match_dup 0))]
-+;   ""
-+;   "bit%0\t%2"
-+;   [(set_attr "length" "3")])
-+; 
-+; (define_peephole
-+;   [(set (match_operand:QI 0 "register_operand" "=q")
-+;     (and:QI (match_operand:QI 1 "register_operand" "0")
-+;       (match_operand:QI 2 "memory_operand" "m")))
-+;    (set (cc0) (match_dup 0))]
-+;   ""
-+;   "bit%0\t%2"
-+;   [(set_attr "length" "4")])
-+
-+
-+;; Turn a "decrement, then test" sequence into just a "decrement".
-+;; The test can be omitted, since it is implicitly done.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "nonimmediate_operand" "")
-+    (plus:QI (match_operand:QI 1 "whole_general_operand" "")
-+    (match_operand:QI 2 "immediate_operand" "")))
-+   (set (cc0) (match_dup 0))]
-+  "m6809_match_peephole2 (PEEP_DEC_IMPLIES_CC, PEEP_END)"
-+  [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))]
-+  "")
-+
-+
-+;; Merge an indexed register increment with a previous usage.
-+;; This is usually done automatically, but not always
-+;; The 'use' should be optional; in all cases where this has been
-+;; seen, it is required though.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+     (mem:QI (match_operand:HI 1 "index_register_operand" "")))
-+   (use (match_dup 0))
-+   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
-+  "m6809_match_peephole2 (PEEP_INDEXED_INC, PEEP_END)"
-+  [(set (match_dup 0) (mem:QI (post_inc:HI (match_dup 1))))
-+   (use (match_dup 0))]
-+  "")
-+
-+
-+;;; Merge "ldX MEM; ldX ,X" into a single instruction using
-+;;; the indirect mode.
-+(define_peephole2
-+  [(set (reg:HI HARD_X_REGNUM)
-+    (mem:HI (match_operand:HI 0 "general_operand" "")))
-+   (set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))]
-+  "reload_completed && m6809_match_peephole2 (PEEP_LDX_INDIRECT, PEEP_END)"
-+  [(set (reg:HI HARD_X_REGNUM)
-+    (mem:HI (mem:HI (match_dup 0))))]
-+  "")
-+
-+
-+;;; Reorder a store followed by a unary operation on that memory
-+;;; so that the unary is performed and then the store.  Consider
-+;;; a binary shift operation, which will be decomposed into
-+;;; identical single shifts, also.
-+;;; TODO - recognize more than just 'ashift' here.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "memory_operand" "")
-+        (match_operand:QI 1 "register_operand" ""))
-+   (set (match_dup 0)
-+        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
-+  "reload_completed"
-+  [(set (match_dup 1)
-+        (ashift:QI (match_dup 1) (match_operand:QI 2 "immediate_operand")))
-+   (set (match_dup 0) (match_dup 1))]
-+  "")
-+
-+;;; Likewise, reorder a unary MEM followed by a load, so that the load
-+;;; is done first, then use the REG instead of the MEM.
-+;;;(define_peephole2
-+;;;  [(set (match_dup 0)
-+;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))
-+;;;   (set (match_operand:QI 0 "register_operand" "")
-+;;;        (match_operand:QI 1 "memory_operand" ""))]
-+;;;  "reload_completed"
-+;;;  [(set (match_dup 0) (match_dup 1))
-+;;;   (set (match_dup 0)
-+;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
-+;;;  "")
-+
-+
-+;;; Replace sex; leaX d,Y with leaX b,Y.
-+;;;
-+(define_peephole2
-+  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
-+   (set (match_operand:HI 0 "index_register_operand" "")
-+        (plus:HI (match_operand:HI 1 "index_register_operand" "")
-+                 (reg:HI HARD_D_REGNUM)))]
-+  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
-+  [(set (match_dup 0)
-+        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
-+  "")
-+
-+(define_peephole2
-+  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
-+   (set (match_operand:HI 0 "index_register_operand" "")
-+        (plus:HI (reg:HI HARD_D_REGNUM)
-+          (match_operand:HI 1 "index_register_operand" "")))]
-+  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
-+  [(set (match_dup 0)
-+        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
-+  "")
-+
-+
-+;;; Replace ldb; decb; stb; tstb with dec(mem).  If the
-+;;; register is not needed, then the load will get deleted
-+;;; automatically, but it may be needed for comparisons.
-+;;; Same for incb/inc.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (match_operand:QI 1 "nonimmediate_operand" ""))
-+   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
-+   (set (match_dup 1) (match_dup 0))
-+   (set (cc0) (match_dup 0))]
-+  "m6809_match_peephole2 (PEEP_MEM_DEC_CMP, PEEP_END)"
-+  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))]
-+  "")
-+
-+
-+;;; Replace ldb; decb; stb with dec(mem); ldb.  If the
-+;;; register is not needed, then the load will get deleted
-+;;; automatically, but it may be needed for comparisons.
-+;;; Same for incb/inc.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (match_operand:QI 1 "nonimmediate_operand" ""))
-+   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
-+   (set (match_dup 1) (match_dup 0))]
-+  "m6809_match_peephole2 (PEEP_MEM_DEC, PEEP_END)"
-+  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
-+   (set (match_dup 0) (match_dup 1))]
-+  "")
-+
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (match_operand:QI 1 "nonimmediate_operand" ""))
-+   (set (match_dup 0) (plus:QI (match_dup 0) (const_int 1)))
-+   (set (match_dup 1) (match_dup 0))]
-+  "m6809_match_peephole2 (PEEP_MEM_INC, PEEP_END)"
-+  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 1)))
-+   (set (match_dup 0) (match_dup 1))]
-+  "")
-+
-+
-+;;; Replace "andb #N; cmpb #N; bhi" with "andb #N", if it can be proven
-+;;; that the branch can never occur because of the limited range of B.
-+;;; N must be a power of two for this to make sense.  This helps with
-+;;; the default cases of switch statements on a value (x & N).
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+    (and:QI (match_dup 0) (match_operand:QI 1 "immediate_operand" "")))
-+   (set (cc0)
-+    (compare (match_dup 0) (match_dup 1)))
-+   (set (pc) (if_then_else (gtu (cc0) (const_int 0)) (match_operand 2 "" "") (match_operand 3 "" "")))
-+   ]
-+  "reload_completed && power_of_two_p (INTVAL (operands[1]) + 1)"
-+  [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
-+  "")
-+
-+;;; Replace ldd <mem>; addd #1; std <mem> with 16-bit increment
-+;;; of the mem, but only if D is dead.  Same for 16-bit decrement.
-+;;; <mem> must be offsettable for the instruction to match.
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
-+   (set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
-+   (set (match_dup 1) (match_dup 0))]
-+   "reload_completed
-+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-+    && peep2_reg_dead_p (3, operands[0])"
-+  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
-+  "")
-+
-+(define_peephole2
-+  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
-+   (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))
-+   (set (match_dup 1) (match_dup 0))]
-+   "reload_completed
-+    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-+    && peep2_reg_dead_p (3, operands[0])"
-+  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int -1)))]
-+  "")
-+
-+
-+;;; Replace a load or store using an indexed register, followed by an increment of that
-+;;; register, with the combined form using autoincrement.
-+(define_peephole2
-+  [(set (match_operand:QI 0 "register_operand" "")
-+        (mem:QI (match_operand:HI 1 "index_register_operand" "")))
-+   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
-+   "reload_completed"
-+  [(set (match_dup 0) (mem:QI (post_inc (match_dup 1))))]
-+  "")
-+
-+
-+;;- mode:emacs-lisp
-+;;- comment-start: ";;- "
-+;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
-+;;- eval: (modify-syntax-entry ?[ "(]")
-+;;- eval: (modify-syntax-entry ?] ")[")
-+;;- eval: (modify-syntax-entry ?{ "(}")
-+;;- eval: (modify-syntax-entry ?} "){")
-+;-; vim: set ts=2:
-+;-; vim: set expandtab:
-+;-; vim: set filetype=lisp:
-+;;- End:
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/m6809.opt gcc-4.6.1/gcc/config/m6809/m6809.opt
---- gcc-4.6.1-orig/gcc/config/m6809/m6809.opt	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/m6809.opt	2011-09-17 14:06:01.227643616 -0600
-@@ -0,0 +1,98 @@
-+; Options for the M6809 port of the compiler
-+;
-+; Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
-+; 02110-1301, USA.
-+
-+margcount
-+Target Mask(ARGCOUNT)
-+Push argument count
-+
-+mint8
-+Target RejectNegative Mask(BYTE_INT)
-+Use 8-bit integers
-+
-+mint16
-+Target RejectNegative
-+Use 16-bit integers InverseMask(BYTE_INT)
-+
-+mreg-args
-+Target Mask(REG_ARGS)
-+Use registers for function arguments
-+
-+mshort_size 
-+Target RejectNegative Mask(SMALL_SIZE_T)
-+Use 8-bit size_t
-+
-+mlong_size
-+Target RejectNegative InverseMask(SMALL_SIZE_T)
-+Use 16-bit size_t
-+
-+mdirect
-+Target Mask(DIRECT)
-+Enable direct addressing
-+
-+mwpc
-+Target RejectNegative Mask(WPC)
-+Enable WPC platform extensions
-+
-+mexperiment
-+Target RejectNegative Mask(EXPERIMENT)
-+Enable current experimental feature
-+
-+m6309
-+Target RejectNegative Mask(6309)
-+Enable Hitachi 6309 extensions
-+
-+mcasesi
-+Target RejectNegative Mask(CASESI)
-+Enable the casesi pattern
-+
-+mfar-code-page=
-+Target RejectNegative Joined Var(far_code_page_option)
-+Sets the far code page value for this compilation unit
-+
-+mcode-section=
-+Target RejectNegative Joined Var(code_section_ptr)
-+Sets the name of the section for code
-+
-+mdata-section=
-+Target RejectNegative Joined Var(data_section_ptr)
-+Sets the name of the section for initialized data
-+
-+mbss-section=
-+Target RejectNegative Joined Var(bss_section_ptr)
-+Sets the name of the section for uninitialized data
-+
-+mabi_version=
-+Target RejectNegative Joined Var(m6809_abi_version_ptr)
-+Sets the calling convention
-+
-+msoft-reg-count=
-+Target RejectNegative Joined Var(m6809_soft_reg_count)
-+Sets the number of soft registers that can be used
-+
-+mdret
-+Target RejectNegative Mask(DRET)
-+Put function call results in D, not X
-+
-+mfar-stack-param
-+Target Mask(FAR_STACK_PARAM)
-+Enable stack parameters to a farcall
-+
-+
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/m6809-protos.h gcc-4.6.1/gcc/config/m6809/m6809-protos.h
---- gcc-4.6.1-orig/gcc/config/m6809/m6809-protos.h	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/m6809-protos.h	2011-09-17 17:26:19.227644879 -0600
-@@ -0,0 +1,94 @@
-+/* GCC for 6809 : machine-specific function prototypes
-+
-+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 __M6809_PROTOS_H__
-+#define __M6809_PROTOS_H__
-+
-+void 					print_options (FILE *file);
-+void 					m6809_cpu_cpp_builtins (void);
-+void 					m6809_override_options (void);
-+void 					m6809_init_builtins (void);
-+unsigned int 		m6809_get_live_regs (void);
-+const char * 		m6809_get_regs_printable (unsigned int regs);
-+unsigned int 		m6809_get_regs_size (unsigned int regs);
-+int 					m6809_function_has_type_attr_p (tree decl, const char *);
-+int 					m6809_current_function_has_type_attr_p (const char *);
-+int 					prologue_epilogue_required (void);
-+int 					noreturn_functionp (rtx x);
-+void 					output_function_prologue (FILE *file, int size);
-+void 					output_function_epilogue (FILE *file, int size);
-+int 					check_float_value (enum machine_mode mode, double *d, int overflow);
-+void 					m6809_asm_named_section (const char *name, unsigned int flags, tree decl);
-+void 					m6809_asm_file_start (void);
-+void              m6809_output_ascii (FILE *fp, const char *str, unsigned long size);
-+void              m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl);
-+void              m6809_reorg (void);
-+int               m6809_current_function_is_void (void);
-+int               m6809_can_merge_pushpop_p (int op, int regs1, int regs2);
-+int               m6809_function_value_regno_p (unsigned int regno);
-+void              emit_prologue_insns (void);
-+void              emit_epilogue_insns (bool);
-+void              m6809_conditional_register_usage (void);
-+void              m6809_output_quoted_string (FILE *asm_file, const char *string);
-+int               m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage);
-+int               m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode);
-+int               power_of_two_p (unsigned int n);
-+void              m6809_do_casesi (rtx index, rtx lower_bound, rtx range, rtx table_label, rtx default_label);
-+void              m6809_output_addsi3 (int rtx_code, rtx *operands);
-+rtx               m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump);
-+void              expand_constant_shift (int code, rtx dst, rtx src, rtx count);
-+int               m6809_single_operand_operator (rtx exp);
-+
-+#ifdef TREE_CODE
-+int m6809_init_cumulative_args (CUMULATIVE_ARGS cum, tree fntype, rtx libname);
-+#endif /* TREE_CODE */
-+
-+#ifdef RTX_CODE
-+void 					print_direct_prefix (FILE *file, rtx addr);
-+void 					print_operand (FILE *file, rtx x, int code);
-+void 					print_operand_address (FILE *file, rtx addr);
-+void 					notice_update_cc (rtx exp, rtx insn);
-+enum 					reg_class m6809_preferred_reload_class (rtx x, enum reg_class regclass);
-+rtx 					gen_rtx_const_high (rtx r);
-+rtx 					gen_rtx_const_low (rtx r);
-+rtx 					gen_rtx_register_pushpop (int pop_flag, int regs);
-+void 					emit_libcall_insns (enum machine_mode mode, const char *name, rtx *operands, int count);
-+const char *		output_branch_insn (enum rtx_code code, rtx *operands, int length);
-+void 					output_far_call_insn (rtx *operands, int has_return);
-+void 					m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt);
-+rtx 					m6809_expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore);
-+const char *      far_functionp (rtx x);
-+rtx               m6809_function_value (const tree valtype, const tree func);
-+void              m6809_output_shift_insn (int rtx_code, rtx *operands);
-+
-+const char * m6809_get_decl_bank (tree decl);
-+void output_branch_insn1 (const char *opcode, rtx *operands, int long_p);
-+rtx m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum);
-+const char * far_function_type_p (tree type);
-+void m6809_asm_trampoline_template(FILE *f);
-+bool m6809_frame_pointer_required (void);
-+int m6809_can_eliminate (int from, int to);
-+int m6809_initial_elimination_offset (int from, int to);
-+void m6809_emit_move_insn (rtx dst, rtx src);
-+void m6809_split_shift (enum rtx_code code, rtx *operands);
-+bool m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED);
-+
-+
-+#endif /* RTX_CODE */
-+
-+#endif /* __M6809_PROTOS_H__ */
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/predicates.md gcc-4.6.1/gcc/config/m6809/predicates.md
---- gcc-4.6.1-orig/gcc/config/m6809/predicates.md	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/predicates.md	2011-09-18 15:09:37.057653095 -0600
-@@ -0,0 +1,78 @@
-+;; Predicate definitions for Motorola 6809
-+;; Copyright (C) 2006, 2007, 2008, 2009 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 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/>.
-+
-+;; whole_register_operand is like register_operand, but it
-+;; does not allow SUBREGs.
-+(define_predicate "whole_register_operand"
-+  (and (match_code "reg")
-+       (match_operand 0 "register_operand")))
-+
-+
-+;; A predicate that matches any index register.  This can be used in nameless
-+;; patterns and peepholes which need a 16-bit reg, but not D.
-+(define_predicate "index_register_operand"
-+  (and (match_code "reg")
-+       (match_test "REGNO (op) == HARD_X_REGNUM || REGNO (op) == HARD_Y_REGNUM || REGNO (op) == HARD_U_REGNUM")))
-+
-+
-+;; match only X
-+(define_predicate "register_operand_x"
-+  (and (match_code "reg")
-+       (match_test "REGNO (op) == HARD_X_REGNUM")))
-+
-+;; match only D
-+(define_predicate "register_operand_d"
-+  (and (match_code "reg")
-+       (match_test "REGNO (op) == HARD_D_REGNUM")))
-+
-+
-+;; Likwise, a replacement for general_operand which excludes
-+;; SUBREGs.
-+(define_predicate "whole_general_operand"
-+  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
-+       (match_operand 0 "general_operand")))
-+
-+
-+(define_predicate "add_general_operand"
-+  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
-+       (match_operand 0 "general_operand")
-+		 (match_test "REGNO (op) != SOFT_AP_REGNUM")))
-+
-+
-+(define_predicate "shift_count_operand"
-+  (and (match_code "const_int")
-+     (and (match_operand 0 "const_int_operand")
-+       (match_test "INTVAL (op) == 1 || INTVAL (op) == 8"))))
-+
-+
-+;; A predicate that matches any bitwise logical operator.  This
-+;; allows for a single RTL pattern to be used for multiple operations.
-+(define_predicate "logical_bit_operator"
-+	(ior (match_code "and") (match_code "ior") (match_code "xor")))
-+
-+
-+;; A predicate that matches any shift or rotate operator.  This
-+;; allows for a single RTL pattern to be used for multiple operations.
-+(define_predicate "shift_rotate_operator"
-+	(ior (match_code "ashift") (match_code "ashiftrt") (match_code "lshiftrt")
-+	     (match_code "rotate") (match_code "rotatert")))
-+
-+
-+(define_predicate "symbolic_operand" (match_code "symbol_ref"))
-+
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/t-coco gcc-4.6.1/gcc/config/m6809/t-coco
---- gcc-4.6.1-orig/gcc/config/m6809/t-coco	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/t-coco	2011-09-17 14:06:01.227643616 -0600
-@@ -0,0 +1,6 @@
-+# For a few minor differences in code generation on the CoCo...
-+T_CFLAGS = -DTARGET_COCO
-+
-+# For doing the startup differently on the CoCo...
-+CRT0STUFF_T_CFLAGS += -Wa,--globalize-symbols -DTARGET_COCO
-+# vim: set filetype=make:
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/t-m6809 gcc-4.6.1/gcc/config/m6809/t-m6809
---- gcc-4.6.1-orig/gcc/config/m6809/t-m6809	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/t-m6809	2011-09-17 21:38:35.437646470 -0600
-@@ -0,0 +1,64 @@
-+
-+# ranlib doesn't exist, so define it to 'true' to make it a no-op
-+RANLIB_FOR_TARGET = true
-+
-+# Stubs for libgcc defined by m6809 are here
-+LIB1ASMSRC = m6809/libgcc1.s
-+
-+# Here are the functions that are implemented within libgcc1.s
-+LIB1ASMFUNCS = _mulhi3 _divhi3 _modhi3 _udivhi3 _umodhi3 \
-+	_euclid _seuclid _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _softregs \
-+	_ashlhi3 _ashrhi3 _lshrhi3
-+
-+# Flags to use when building libgcc.  IN_GCC does not seem necessary,
-+# although the compile breaks without it.  -DDF=SF is required to set
-+# the size of "double" to the same as the size of a "float".
-+TARGET_LIBGCC2_CFLAGS =-DIN_GCC -Dinhibit_libc -DDF=SF -DLIBGCC2_HAS_SF_MODE=0 -DLIBGCC2_HAS_DF_MODE=0
-+
-+LIB2ADDEH =
-+LIB2ADDEHSTATIC =
-+LIB2ADDEHSHARED =
-+
-+LIBGCC2_DEBUG_CFLAGS =
-+LIBGCC2_CFLAGS = -Os $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
-+
-+# Multilib information
-+# This creates multiple versions of libgcc.a for each set of incompatible
-+# -mxxx options.
-+MULTILIB_OPTIONS  = fpic mdret
-+MULTILIB_DIRNAMES =
-+MULTILIB_MATCHES  =
-+MULTILIB_EXCEPTIONS =
-+EXTRA_MULTILIB_PARTS = crt0.o
-+
-+LIBGCC = stmp-multilib
-+INSTALL_LIBGCC = install-multilib
-+
-+# We want fine grained libraries, so use the new code to build the
-+# floating point emulation libraries.
-+FPBIT = fp-bit.c
-+
-+fp-bit.c: $(srcdir)/config/fp-bit.c
-+	echo '#define FLOAT' > fp-bit.c
-+	echo '#define FLOAT_ONLY' >> fp-bit.c
-+	echo '#define CMPtype HItype' >> fp-bit.c
-+	echo '#define SMALL_MACHINE' >> fp-bit.c
-+	echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
-+	echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
-+	echo '#endif' 		>> fp-bit.c
-+	echo '#define DI SI'	>> fp-bit.c
-+	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-+
-+# crt0.o is built from the following source file
-+CRT0_S = $(srcdir)/config/m6809/crt0.S
-+MCRT0_S = $(srcdir)/config/m6809/crt0.S
-+
-+# Flags to use when building crt0.o
-+CRT0STUFF_T_CFLAGS += -fno-builtin -nostartfiles -nostdlib
-+
-+# Assemble startup files.
-+$(T)crt0.o: $(CRT0_S) $(GCC_PASSES)
-+	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)crt0.o -x assembler-with-cpp $(CRT0_S)
-+
-+$(T)mcrt0.o: $(MCRT0_S) $(GCC_PASSES)
-+	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)mcrt0.o -x assembler-with-cpp $(MCRT0_S)
-diff -urN gcc-4.6.1-orig/gcc/config/m6809/t-sim gcc-4.6.1/gcc/config/m6809/t-sim
---- gcc-4.6.1-orig/gcc/config/m6809/t-sim	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/gcc/config/m6809/t-sim	2011-09-17 14:06:01.227643616 -0600
-@@ -0,0 +1 @@
-+CRT0STUFF_T_CFLAGS += -DTARGET_SIM
-diff -urN gcc-4.6.1-orig/gcc/config.gcc gcc-4.6.1/gcc/config.gcc
---- gcc-4.6.1-orig/gcc/config.gcc	2011-05-22 14:03:43.000000000 -0600
-+++ gcc-4.6.1/gcc/config.gcc	2011-09-17 14:08:56.257643636 -0600
-@@ -374,6 +374,9 @@
-         cpu_type=m32r
- 	extra_options="${extra_options} g.opt"
-         ;;
-+m6809-*-*)
-+        cpu_type=m6809
-+        ;;
- m68k-*-*)
- 	extra_headers=math-68881.h
- 	;;
-@@ -1689,6 +1692,12 @@
- 		thread_file='posix'
- 	fi
- 	;;
-+m6809-coco-*)
-+	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-coco"
-+	;;
-+m6809-*-*)
-+	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-sim"
-+	;;
- # m68hc11 and m68hc12 share the same machine description.
- m68hc11-*-*|m6811-*-*)
- 	tm_file="dbxelf.h elfos.h usegas.h newlib-stdint.h m68hc11/m68hc11.h"
-diff -urN gcc-4.6.1-orig/gcc/gcse.c gcc-4.6.1/gcc/gcse.c
---- gcc-4.6.1-orig/gcc/gcse.c	2011-02-02 23:04:04.000000000 -0700
-+++ gcc-4.6.1/gcc/gcse.c	2011-09-18 17:25:17.527653952 -0600
-@@ -833,7 +833,6 @@
- 	      max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
- 	      if (max_distance == 0)
- 		return 0;
--
- 	      gcc_assert (max_distance > 0);
- 	    }
- 	  else
-diff -urN gcc-4.6.1-orig/gcc/libgcc2.c gcc-4.6.1/gcc/libgcc2.c
---- gcc-4.6.1-orig/gcc/libgcc2.c	2011-01-03 13:52:22.000000000 -0700
-+++ gcc-4.6.1/gcc/libgcc2.c	2011-09-17 14:06:01.227643616 -0600
-@@ -485,6 +485,7 @@
- #endif
- 
- #ifdef L_bswapsi2
-+#if MIN_UNITS_PER_WORD > 1
- SItype
- __bswapsi2 (SItype u)
- {
-@@ -494,7 +495,9 @@
- 	  | (((u) & 0x000000ff) << 24));
- }
- #endif
-+#endif
- #ifdef L_bswapdi2
-+#if LONG_LONG_TYPE_SIZE > 32
- DItype
- __bswapdi2 (DItype u)
- {
-@@ -508,6 +511,7 @@
- 	  | (((u) & 0x00000000000000ffull) << 56));
- }
- #endif
-+#endif
- #ifdef L_ffssi2
- #undef int
- int
-@@ -1280,7 +1284,7 @@
- UDWtype
- __fixunssfDI (SFtype a)
- {
--#if LIBGCC2_HAS_DF_MODE
-+#if LIBGCC2_HAS_DF_MODE || (FLT_MANT_DIG >= W_TYPE_SIZE)
-   /* Convert the SFtype to a DFtype, because that is surely not going
-      to lose any bits.  Some day someone else can write a faster version
-      that avoids converting to DFtype, and verify it really works right.  */
-@@ -1298,7 +1302,7 @@
- 
-   /* Assemble result from the two parts.  */
-   return ((UDWtype) hi << W_TYPE_SIZE) | lo;
--#elif FLT_MANT_DIG < W_TYPE_SIZE
-+#else
-   if (a < 1)
-     return 0;
-   if (a < Wtype_MAXp1_F)
-@@ -1334,8 +1338,6 @@
-       return (DWtype)counter << shift;
-     }
-   return -1;
--#else
--# error
- #endif
- }
- #endif
-diff -urN gcc-4.6.1-orig/gcc/longlong.h gcc-4.6.1/gcc/longlong.h
---- gcc-4.6.1-orig/gcc/longlong.h	2011-06-06 08:34:54.000000000 -0600
-+++ gcc-4.6.1/gcc/longlong.h	2011-09-17 14:06:01.227643616 -0600
-@@ -527,6 +527,11 @@
- 	   : "cbit")
- #endif /* __M32R__ */
- 
-+#if defined (__m6309__) || defined (__m6809__)
-+#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
-+#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctz (X))
-+#endif
-+
- #if defined (__mc68000__) && W_TYPE_SIZE == 32
- #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
-   __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
-diff -urN gcc-4.6.1-orig/gcc/Makefile.in gcc-4.6.1/gcc/Makefile.in
---- gcc-4.6.1-orig/gcc/Makefile.in	2011-05-23 12:12:34.000000000 -0600
-+++ gcc-4.6.1/gcc/Makefile.in	2011-09-17 14:06:01.197643616 -0600
-@@ -1987,14 +1987,14 @@
- 
- # Compile the start modules crt0.o and mcrt0.o that are linked with
- # every program
--$(T)crt0.o: s-crt0 ; @true
--$(T)mcrt0.o: s-crt0; @true
-+crt0.o: s-crt0 ; @true
-+mcrt0.o: s-crt0; @true
- 
- s-crt0:	$(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
- 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
--	  -o $(T)crt0.o -c $(CRT0_S)
-+	  -o crt0.o -c $(CRT0_S)
- 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
--	  -o $(T)mcrt0.o -c $(MCRT0_S)
-+	  -o mcrt0.o -c $(MCRT0_S)
- 	$(STAMP) s-crt0
- #
- # Compiling object files from source files.
-diff -urN gcc-4.6.1-orig/gcc/opth-gen.awk gcc-4.6.1/gcc/opth-gen.awk
---- gcc-4.6.1-orig/gcc/opth-gen.awk	2011-02-08 10:41:00.000000000 -0700
-+++ gcc-4.6.1/gcc/opth-gen.awk	2011-09-17 14:06:01.227643616 -0600
-@@ -121,7 +121,7 @@
- END {
- print "/* This file is auto-generated by opth-gen.awk.  */"
- print ""
--print "#ifndef OPTIONS_H"
-+print "#if !defined(OPTIONS_H) && !defined(IN_LIBGCC2)"
- print "#define OPTIONS_H"
- print ""
- print "#include \"flag-types.h\""
-@@ -432,18 +432,9 @@
- 
- for (i = 0; i < n_opts; i++) {
- 	opt = opt_args("InverseMask", flags[i])
--	if (opt ~ ",") {
--		vname = var_name(flags[i])
--		macro = "OPTION_"
--		mask = "OPTION_MASK_"
--		if (vname == "") {
--			vname = "target_flags"
--			macro = "TARGET_"
--			mask = "MASK_"
--		}
--		print "#define " macro nth_arg(1, opt) \
--		      " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
--	}
-+	if (opt ~ ",")
-+		print "#define TARGET_" nth_arg(1, opt) \
-+		      " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
- }
- print ""
- 
-diff -urN gcc-4.6.1-orig/gcc/tree.h gcc-4.6.1/gcc/tree.h
---- gcc-4.6.1-orig/gcc/tree.h	2011-06-14 09:28:21.000000000 -0600
-+++ gcc-4.6.1/gcc/tree.h	2011-09-17 20:28:05.987646026 -0600
-@@ -3563,6 +3563,8 @@
-   TI_UINTDI_TYPE,
-   TI_UINTTI_TYPE,
- 
-+  TI_UINT8_TYPE,
-+  TI_UINT16_TYPE,
-   TI_UINT32_TYPE,
-   TI_UINT64_TYPE,
- 
-diff -urN gcc-4.6.1-orig/gcc/version.c gcc-4.6.1/gcc/version.c
---- gcc-4.6.1-orig/gcc/version.c	2009-04-21 13:03:23.000000000 -0600
-+++ gcc-4.6.1/gcc/version.c	2011-09-18 19:49:48.437654863 -0600
-@@ -21,16 +21,16 @@
- 
- /* This is the location of the online document giving instructions for
-    reporting bugs.  If you distribute a modified version of GCC,
--   please configure with --with-bugurl pointing to a document giving
--   instructions for reporting bugs to you, not us.  (You are of course
--   welcome to forward us bugs reported to you, if you determine that
--   they are not bugs in your modifications.)  */
-+   please change this to refer to a document giving instructions for
-+   reporting bugs to you, not us.  (You are of course welcome to
-+   forward us bugs reported to you, if you determine that they are
-+   not bugs in your modifications.)  */
- 
--const char bug_report_url[] = BUGURL;
-+const char bug_report_url[] = "<URL:http://lost.l-w.ca/coco/lwtools/>";
- 
- /* The complete version string, assembled from several pieces.
-    BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the
-    Makefile.  */
- 
--const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION;
-+const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION " (gcc6809lw)";
- const char pkgversion_string[] = PKGVERSION;
-diff -urN gcc-4.6.1-orig/libgcc/config.host gcc-4.6.1/libgcc/config.host
---- gcc-4.6.1-orig/libgcc/config.host	2011-03-14 00:06:23.000000000 -0600
-+++ gcc-4.6.1/libgcc/config.host	2011-09-17 14:06:01.257643616 -0600
-@@ -380,6 +380,8 @@
-  	;;
- m32rle-*-linux*)
- 	;;
-+m6809*)
-+	;;
- m68hc11-*-*|m6811-*-*)
-         ;;
- m68hc12-*-*|m6812-*-*)
-diff -urN gcc-4.6.1-orig/libgcc/fixed-obj.mk gcc-4.6.1/libgcc/fixed-obj.mk
---- gcc-4.6.1-orig/libgcc/fixed-obj.mk	2007-09-17 16:18:13.000000000 -0600
-+++ gcc-4.6.1/libgcc/fixed-obj.mk	2011-09-17 14:06:01.257643616 -0600
-@@ -23,7 +23,7 @@
- #$(info $o$(objext): -DL$($o-label) $($o-opt))
- 
- $o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
--	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
-+	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide) -save-temps
- 
- ifeq ($(enable_shared),yes)
- $(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
-diff -urN gcc-4.6.1-orig/libgcc/Makefile.in gcc-4.6.1/libgcc/Makefile.in
---- gcc-4.6.1-orig/libgcc/Makefile.in	2011-01-25 21:19:58.000000000 -0700
-+++ gcc-4.6.1/libgcc/Makefile.in	2011-09-17 14:06:01.257643616 -0600
-@@ -374,8 +374,8 @@
- # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
- lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
- $(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c
--	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
--	  $(vis_hide)
-+	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
-+	$(gcc_compile) -DL$* -c $*.c $(vis_hide) -save-temps
- libgcc-objects += $(lib2funcs-o)
- 
- ifeq ($(enable_shared),yes)
-@@ -410,8 +410,9 @@
- # Build LIB2_DIVMOD_FUNCS.
- lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
- $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
--	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
--	  -fexceptions -fnon-call-exceptions $(vis_hide)
-+	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
-+	$(gcc_compile) -DL$* -c $*.c \
-+	  -fexceptions -fnon-call-exceptions $(vis_hide) -save-temps
- libgcc-objects += $(lib2-divmod-o)
- 
- ifeq ($(enable_shared),yes)
-@@ -443,7 +444,8 @@
- ifneq ($(FPBIT),)
- fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
- $(fpbit-o): %$(objext): $(FPBIT)
--	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
-+	ln -sf $(FPBIT) $*.c && \
-+	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
- libgcc-objects += $(fpbit-o)
- 
- ifeq ($(enable_shared),yes)
-@@ -458,7 +460,8 @@
- ifneq ($(DPBIT),)
- dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
- $(dpbit-o): %$(objext): $(DPBIT)
--	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
-+	ln -sf $(DPBIT) $*.c && \
-+	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
- libgcc-objects += $(dpbit-o)
- 
- ifeq ($(enable_shared),yes)
-diff -urN gcc-4.6.1-orig/README.LW gcc-4.6.1/README.LW
---- gcc-4.6.1-orig/README.LW	1969-12-31 17:00:00.000000000 -0700
-+++ gcc-4.6.1/README.LW	2011-09-18 19:44:52.457654831 -0600
-@@ -0,0 +1,14 @@
-+This is a port of gcc6809 which is designed to work with the lwtools
-+cross-assembler and linker package.  You will need several scripts from that
-+package, available at http://lost.l-w.ca/coco/lwtools/, in order to use
-+this.  Instructions for building are present in the lwtools package.
-+
-+This work is based extensively on the gcc6809 4.3.4-3 release by Brian
-+Dominy (brian@oddchange.com) with some significant renovations to make it
-+work with gcc 4.6.1.
-+
-+There is no guarantee that it will work for any particular purpose you
-+choose to put it to.
-+
-+If you run into any problems, contact William Astle (lost@l-w.ca). DO NOT
-+contact the main GCC developers!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/gcc6809lw-4.6.4-7.patch	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,8164 @@
+diff -urN gcc-4.6.4-clean/config.sub gcc-4.6.4/config.sub
+--- gcc-4.6.4-clean/config.sub	2010-05-25 07:22:07.000000000 -0600
++++ gcc-4.6.4/config.sub	2015-07-20 19:44:52.766843181 -0600
+@@ -313,7 +313,7 @@
+ 	c6x)
+ 		basic_machine=tic6x-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
++	m6809 | m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ 		# Motorola 68HC11/12.
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+@@ -354,7 +354,7 @@
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
+ 	| lm32-* \
+-	| m32c-* | m32r-* | m32rle-* \
++	| m32c-* | m32r-* | m32rle-* | m6809-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ 	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+@@ -509,6 +509,10 @@
+ 		basic_machine=arm-unknown
+ 		os=-cegcc
+ 		;;
++	coco)
++		basic_machine=coco
++		os=-none
++		;;
+ 	convex-c1)
+ 		basic_machine=c1-convex
+ 		os=-bsd
+diff -urN gcc-4.6.4-clean/configure gcc-4.6.4/configure
+--- gcc-4.6.4-clean/configure	2011-12-18 03:03:44.000000000 -0700
++++ gcc-4.6.4/configure	2015-07-20 19:44:52.766843181 -0600
+@@ -3439,6 +3439,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/configure.ac gcc-4.6.4/configure.ac
+--- gcc-4.6.4-clean/configure.ac	2011-11-18 04:45:44.000000000 -0700
++++ gcc-4.6.4/configure.ac	2015-07-20 19:44:52.766843181 -0600
+@@ -885,6 +885,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/gcc/calls.c gcc-4.6.4/gcc/calls.c
+--- gcc-4.6.4-clean/gcc/calls.c	2012-02-09 10:27:25.000000000 -0700
++++ gcc-4.6.4/gcc/calls.c	2015-07-20 19:44:52.766843181 -0600
+@@ -2561,7 +2561,7 @@
+ 	 call sequence.
+ 	 Also do the adjustments before a throwing call, otherwise
+ 	 exception handling can fail; PR 19225. */
+-      if (pending_stack_adjust >= 32
++      if (pending_stack_adjust >= 8
+ 	  || (pending_stack_adjust > 0
+ 	      && (flags & ECF_MAY_BE_ALLOCA))
+ 	  || (pending_stack_adjust > 0
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/crt0.S gcc-4.6.4/gcc/config/m6809/crt0.S
+--- gcc-4.6.4-clean/gcc/config/m6809/crt0.S	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/crt0.S	2015-07-20 19:44:52.766843181 -0600
+@@ -0,0 +1,173 @@
++;;;
++;;; Copyright 2006, 2007, 2008, 2009 by Brian Dominy <brian@oddchange.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/>.
++
++	/* Declare external for main() */
++	.globl _main
++
++
++/* The startup is heavily dependent on the type of machine and
++OS environment that is available at the start point.
++For the most part, the general idea is the same across machines,
++but the implementation is vastly different.  This is managed via
++conditional compiles throughout the startup code for each of the
++supported machines. */
++
++#ifdef TARGET_COCO /* CoCo memory map */
++
++#define COCO_RAMROM_MODE 0xFFDE
++#define COCO_ALLRAM_MODE 0xFFDF
++#define COCO_PAGE1 0xFFD5
++
++/* SAM M1 and M0 adjusts the memory size */
++
++#define BASIC_WARMSTART_FLAG 0x0071
++#define BASIC_START 0xA027
++
++#define __STACK_TOP 0x6800
++
++#else /* Simulator (default) memory map */
++
++#define SIM_EXIT_REG 0xFF01
++
++#define __STACK_TOP 0xFE00
++
++#endif
++
++
++	.area .data
++	.area .ctors
++	.area .dtors
++	.area .bss
++
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __exit : Exit point from the program
++	;;; For simulation, this writes to a special I/O register that
++	;;; the simulator interprets as end-of-program.
++	;;;
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++ 	.globl __exit
++__exit:
++#ifdef TARGET_COCO
++	;; Go back to ROM/RAM mode
++	sta	COCO_RAMROM_MODE
++	clr	BASIC_WARMSTART_FLAG
++	jmp   BASIC_START
++#else
++	tfr	x,d
++	stb	SIM_EXIT_REG
++	bra	__exit
++#endif
++
++
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __start : Entry point to the program
++	;;;
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++	.globl __start
++__start:
++
++#ifdef HAVE_DIRECT
++	;; Initialize the direct page pointer
++	lda	#<s_.direct
++	tfr	a,dp
++#endif
++
++#ifdef TARGET_COCO
++	;; Turn off interrupts
++	orcc #(0x10|0x40)
++	
++	;; Setup All RAM Mode
++	sta COCO_ALLRAM_MODE
++#endif /* TARGET_COCO */
++
++	;; Initialize the stack
++	lds	#__STACK_TOP - 2
++	
++	;; Call any "initializer" functions
++	ldu	#s_.ctors
++__ctors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__ctors_done
++	jsr	,y
++	bra	__ctors_loop
++__ctors_done:
++
++	;; Enable interrupts on the simulator
++#ifndef TARGET_COCO
++	andcc	#~(0x10|0x40)
++#endif
++
++	;; Set up the environment
++
++	;; Set up argc/argv arrays
++
++	;; Call the main function.  The exit code will
++	;; be returned in the X register, unless compiled
++	;; with -mdret, in which case it comes back in D.
++	jsr	_main
++
++	;; Call any finalizer functions
++	ldu	#s_.dtors
++__dtors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__dtors_done
++	jsr	,y
++	bra	__dtors_loop
++__dtors_done:
++
++	;; If main returns, then invoke _exit() to stop the program
++	;; The C library doesn't support -mdret yet, so move the
++	;; argument first.
++#ifdef __DRET__
++	tfr	d,x
++#endif
++	jmp	_exit
++
++
++
++	;;;
++	;;; __crt0_vector : Default handler for interrupts
++	;;;
++	.area	.text
++___crt0_vector:
++	;; The default behavior is to simply ignore all
++	;; non-reset interrupts.
++	rti
++
++
++	;;;
++	;;; vector : The interrupt vector table
++	;;; The linker will ensure that this gets loaded at address 0xFFF0.
++	;;;
++	.area vector
++vectors:
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word __start
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s gcc-4.6.4/gcc/config/m6809/libgcc1.s
+--- gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/libgcc1.s	2015-07-20 19:44:52.766843181 -0600
+@@ -0,0 +1,511 @@
++/* libgcc routines for m6809
++   Copyright (C) 2006 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 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/>.  */
++
++/* As a special exception, if you link this library with other files,
++   some of which are compiled with GCC, to produce an executable,
++   this library does not by itself cause the resulting executable
++   to be covered by the GNU General Public License.
++   This exception does not however invalidate any other reasons why
++   the executable file might be covered by the GNU General Public License.  */
++
++
++#define SIGFPE jmp _abort
++
++
++	; Shift functions
++	; On input, D is value to be shifted, and X has shift count.
++	; Result is also in D.
++
++#ifdef L_ashlhi3
++	.area .text
++	.globl _ashlhi3
++_ashlhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	aslb
++	rola
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++#ifdef L_ashrhi3
++	.area .text
++	.globl _ashrhi3
++_ashrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	asra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++#ifdef L_lshrhi3
++	.area .text
++	.globl _lshrhi3
++_lshrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	lsra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++
++#ifdef L_softregs
++	.area		direct
++	.globl	m0, m1, m2, m3, m4, m5, m6, m7
++	.globl	m8, m9, m10, m11, m12, m13, m14, m15
++m0: .blkb 1
++m1: .blkb 1
++m2: .blkb 1
++m3: .blkb 1
++m4: .blkb 1
++m5: .blkb 1
++m6: .blkb 1
++m7: .blkb 1
++m8: .blkb 1
++m9: .blkb 1
++m10: .blkb 1
++m11: .blkb 1
++m12: .blkb 1
++m13: .blkb 1
++m14: .blkb 1
++m15: .blkb 1
++#endif
++
++
++#ifdef L_ashlsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashlsi3_one:
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	rts
++#endif
++
++#ifdef L_ashlsi3
++	/* X points to the SImode (source/dest)
++		B is the count */
++_ashlsi3:
++	pshs	u
++	cmpb	#16
++	blt	try8
++	subb	#16
++	; Shift by 16
++	ldu	2,x
++	stu	,x
++try8:
++	cmpb	#8
++	blt	try_rest
++	subb	#8
++	; Shift by 8
++
++try_rest:
++	tstb
++	beq	done
++do_rest:
++	; Shift by 1
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	decb
++	bne	do_rest
++done:
++	puls	u,pc
++#endif
++
++#ifdef L_ashrsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashrsi3_one:
++	asr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_lshrsi3_one
++	.area		.text
++	.globl	_lshrsi3_one
++_lshrsi3_one:
++	lsr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_clzsi2
++	.area .text
++	.globl ___clzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of leading zeros
++	; This function destroys the value in D.
++___clzhi2:
++	pshs	x
++	; Find the offset of the leftmost '1' bit in
++	; the left half of the word.
++	;
++	; Bits are numbered in the table with 1 meaning the
++	; LSB and 8 meaning the MSB.
++	;
++	; If nonzero, then clz is 8-a.
++	tfr	x,d
++	ldx	#___clz_tab
++	tfr	a,b
++	clra
++	ldb	d,x
++	bne	upper_bit_set
++
++lower_bit_set:
++	; If the upper byte is zero, then check the lower
++	; half of the word.  Return 16-a.
++	puls	d
++	clra
++	ldb	d,x
++	negb
++	addb	#16
++	bra	done
++
++upper_bit_set:
++	negb
++	addb	#8
++	puls	x
++
++done:
++	tfr	d,x
++	puls	pc
++#endif
++
++#ifdef L_clzdi2
++	.area .text
++	.globl ___clzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___clzsi2:
++	; Check the upper 16-bit word
++	; If it is not zero, then return clzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	2,s
++	lbne	___clzhi2
++	ldx	4,s
++	jsr	___clzhi2
++	leax	16,x
++	rts
++#endif
++
++#ifdef L_ctzsi2
++	.area .text
++	.globl ___ctzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of trailing zeros
++	; F(x) = 15 - clzhi2(X & -x)
++	; This function destroys the value in D.
++___ctzhi2:
++	tfr	x,d
++	coma
++	comb
++	addd	#1
++	pshs	a
++	pshs	b
++	tfr	x,d
++	andb	,s+
++	anda	,s+
++	tfr	d,x
++	jsr	___clzhi2
++	tfr	x,d
++	subd	#16
++	coma
++	comb
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_ctzdi2
++	.area .text
++	.globl ___ctzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___ctzsi2:
++	; Check the lower 16-bit word
++	; If it is not zero, then return ctzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	4,s
++	lbne	___ctzhi2
++	ldx	2,s
++	jsr	___ctzhi2
++	leax	16,x
++	rts
++#endif
++
++
++#ifdef L_mulhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___mulhi3 - signed/unsigned multiply
++;;; Called by GCC to implement 16x16 multiplication
++;;; Arguments: Two 16-bit values, one in stack, one in X.
++;;; Result: 16-bit result in X
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _mulhi3
++_mulhi3:
++	pshs	x
++	lda   5,s   ; left msb * right lsb * 256
++	ldb   ,s
++	mul
++	tfr   b,a
++	clrb
++	tfr   d,x
++	ldb   1,s   ; left lsb * right msb * 256
++	lda   4,s
++	mul
++	tfr   b,a
++	clrb
++	leax  d,x
++	ldb   1,s   ; left lsb * right lsb
++	lda   5,s
++	mul
++	leax  d,x
++	puls	d,pc  ; kill D to remove initial push
++#endif
++
++
++#ifdef L_divhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___divhi3 - signed division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _divhi3
++_divhi3:
++	ldd	2,s
++	bne	do_div		; check dividend
++	SIGFPE
++do_div:
++	pshs	x
++	jsr	_seuclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_modhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___modhi3 - signed modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _modhi3
++_modhi3:
++	ldd	2,s
++	bne	do_mod		; check dividend
++	SIGFPE
++do_mod:
++	pshs	x
++	jsr	_seuclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++
++#ifdef L_udivhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___udivhi3 - unsigned division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _udivhi3
++_udivhi3:
++	ldd	2,s
++	bne	do_udiv		; check dividend
++	SIGFPE
++do_udiv:
++	pshs	x
++	jsr	_euclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_umodhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___umodhi3 - unsigned modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _umodhi3
++_umodhi3:
++	ldd	2,s
++	bne	do_umod		; check dividend
++	SIGFPE
++do_umod:
++	pshs	x
++	jsr	_euclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_euclid
++;	unsigned euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _euclid
++;	quotient on the stack (left)
++;	modulus in d
++
++	.area	.text
++	.globl	_euclid
++	left=5
++	right=1			; word
++	count=0			; byte
++	CARRY=1			; alias
++_euclid:
++	leas	-3,s		; 2 local variables
++	clr	count,s		; prescale divisor
++	inc	count,s
++	tsta
++presc:
++	bmi	presc_done
++	inc	count,s
++	aslb
++	rola
++	bra	presc
++presc_done:
++	std	right,s
++	ldd	left,s
++	clr	left,s		; quotient = 0
++	clr	left+1,s
++mod1:
++	subd	right,s		; check subtract
++	bcc	mod2
++	addd	right,s
++	andcc	#~CARRY
++	bra	mod3
++mod2:
++	orcc	#CARRY
++mod3:
++	rol	left+1,s	; roll in carry
++	rol	left,s
++	lsr	right,s
++	ror	right+1,s
++	dec	count,s
++	bne	mod1
++	leas	3,s
++	rts
++#endif
++
++#ifdef L_seuclid
++;	signed euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _seuclid
++;	quotient on the stack (left)
++;	modulus in d
++	.area	.text
++	.globl	_seuclid
++	left=6
++	right=2
++	quot_sign=1
++	mod_sign=0
++_seuclid:
++	leas	-4,s		; 3 local variables
++	std	right,s
++	clr	mod_sign,s
++	clr	quot_sign,s
++	ldd	left,s
++	bge	mod_abs
++	inc	mod_sign,s	; sign(mod) = sign(left)
++	inc	quot_sign,s
++	bsr	negd		; abs(left) -> D
++mod_abs:
++	pshs	b,a		; push abs(left)
++	ldd	right+2,s	; all references shifted by 2
++	bge	quot_abs
++	dec	quot_sign+2,s	; sign(quot) = sign(left) XOR sign(right)
++	bsr	negd		; abs(right) -> D
++quot_abs:
++	jsr	_euclid		; call (unsigned) euclidean division
++	std	right+2,s
++	puls	a,b		; quot -> D
++	tst	quot_sign,s	; all references no longer shifted
++	beq	quot_done
++	bsr	negd
++quot_done:
++	std	left,s		; quot -> left
++	ldd	right,s
++	tst	mod_sign,s
++	beq	mod_done
++	bsr	negd
++mod_done:
++	leas	4,s		; destroy stack frame
++	rts
++
++negd:				; self-explanatory !
++	nega
++	negb
++	sbca	#0
++	rts
++#endif
++
++
++
++#ifdef L_pending_addsi3
++_addsi3:
++	rts
++#endif /* L_pending_addsi3 */
++
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.c gcc-4.6.4/gcc/config/m6809/m6809.c
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.c	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.c	2015-07-20 22:11:37.726714746 -0600
+@@ -0,0 +1,3025 @@
++/*-------------------------------------------------------------------
++	FILE: m6809.c
++-------------------------------------------------------------------*/
++/* Subroutines for insn-output.c for MC6809.
++   Copyright (C) 1989-2007 Free Software Foundation, Inc.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ major cleanup, improvements, and upgrade to gcc 3.4 by Brian Dominy
++ (brian@oddchange.com)
++
++ additional adjustments, etc., for gcc 4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++#include <string.h>
++#include <time.h>
++#include <sys/types.h>
++#include <sys/timeb.h>
++#include <stdio.h>
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "tree.h"
++#include "rtl.h"
++#include "tm_p.h"
++#include "regs.h"
++#include "flags.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "tree.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-flags.h"
++#include "output.h"
++#include "insn-attr.h"
++#include "function.h"
++#include "target.h"
++#include "target-def.h"
++#include "expr.h"
++#include "recog.h"
++#include "cpplib.h"
++#include "c-family/c-pragma.h"
++#include "c-family/c-common.h"
++#include "toplev.h"
++#include "optabs.h"
++#include "version.h"
++#include "df.h"
++#include "rtlhooks-def.h"
++
++/* macro to return TRUE if length of operand mode is one byte */
++#define BYTE_MODE(X) ((GET_MODE_SIZE (GET_MODE (X))) == 1)
++
++
++/* REAL_REG_P(x) is a true if the rtx 'x' represents a real CPU
++register and not a fake one that is emulated in software. */
++#define REAL_REG_P(x) (REG_P(x) && !M_REG_P(x))
++
++/*-------------------------------------------------------------------
++    Target hooks, moved from target.h
++-------------------------------------------------------------------*/
++static void m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED);
++
++#undef TARGET_ENCODE_SECTION_INFO
++#define TARGET_ENCODE_SECTION_INFO m6809_encode_section_info
++
++#undef TARGET_ASM_FILE_START
++#define TARGET_ASM_FILE_START m6809_asm_file_start
++
++#undef TARGET_ASM_ALIGNED_HI_OP
++#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_ALIGNED_SI_OP
++#define TARGET_ASM_ALIGNED_SI_OP NULL
++
++#undef TARGET_ASM_UNALIGNED_HI_OP
++#define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_UNALIGNED_SI_OP
++#define TARGET_ASM_UNALIGNED_SI_OP NULL
++
++#undef TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS m6809_rtx_costs
++
++#undef TARGET_ATTRIBUTE_TABLE
++#define TARGET_ATTRIBUTE_TABLE m6809_attribute_table
++
++#undef TARGET_INIT_BUILTINS
++#define TARGET_INIT_BUILTINS m6809_init_builtins
++
++#undef TARGET_EXPAND_BUILTIN
++#define TARGET_EXPAND_BUILTIN m6809_expand_builtin
++
++#undef TARGET_DEFAULT_TARGET_FLAGS
++#define TARGET_DEFAULT_TARGET_FLAGS (MASK_REG_ARGS | MASK_DIRECT)
++
++#undef TARGET_FUNCTION_OK_FOR_SIBCALL
++#define TARGET_FUNCTION_OK_FOR_SIBCALL m6809_function_ok_for_sibcall
++
++#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
++#define TARGET_ASM_TRAMPOLINE_TEMPLATE m6809_asm_trampoline_template
++
++#undef TARGET_TRAMPOLINE_INIT
++#define TARGET_TRAMPOLINE_INIT m6809_initialize_trampoline
++
++#undef TARGET_FRAME_POINTER_REQUIRED
++#define TARGET_FRAME_POINTER_REQUIRED m6809_frame_pointer_required
++
++#undef TARGET_OPTION_OVERRIDE
++#define TARGET_OPTION_OVERRIDE m6809_override_options
++
++/* External variables used */
++extern int reload_completed;   /* set in toplev.c */
++extern FILE *asm_out_file;
++
++static int last_mem_size;   /* operand size (bytes) */
++
++/* True if the section was recently changed and another .area
++ * directive needs to be output before emitting the next label. */
++int section_changed = 0;
++
++/* Section names.  The defaults here are used until an
++ * __attribute__((section)) is seen that changes it. */
++char code_section_op[128] = "\t.area .text";
++char data_section_op[128] = "\t.area .data";
++char bss_section_op[128] = "\t.area .bss";
++const char *code_bank_option = 0;
++
++/* TRUE if the direct mode prefix might be valid in this context.
++ * This is set by 'print_address' prior to calling output_addr_const,
++ * which performs into 'print_direct_prefix' to do the final checks. */
++static int check_direct_prefix_flag;
++
++/* Nonzero if an address is being printed in a context which does not
++ * permit any PIC modifications to the address */
++static int pic_ok_for_addr_p = 1;
++
++/* Current code page.  This supports machines which can do bank
++ * switching to allow for more than 64KB of code/data. */
++char far_code_page[64];
++
++/* Current bank name */
++static char current_bank_name[8] = "-1";
++
++/* Default bank name */
++static char default_code_bank_name[8] = "-1";
++
++/* Direct memory reserved as soft registers */
++unsigned int m6809_soft_regs = 0;
++
++/* ABI version */
++unsigned int m6809_abi_version = M6809_ABI_VERSION_REGS;
++
++
++/**
++ * Called after options have been parsed.
++ * If overrides have been specified on the command-line, then
++ * these values are copied into the main storage variables.
++ */
++void
++m6809_override_options (void)
++{
++	/* Handle -mfar-code-page */
++	if (far_code_page_option == 0)
++		far_code_page_option = "__default_code_page";
++	strcpy (far_code_page, far_code_page_option);
++
++	/* Handle -mcode-section, -mdata-section, and -mbss-section */
++	if (code_section_ptr != 0)
++		sprintf (code_section_op, "\t.area %s", code_section_ptr);
++	if (data_section_ptr != 0)
++		sprintf (data_section_op, "\t.area %s", data_section_ptr);
++	if (bss_section_ptr != 0)
++		sprintf (bss_section_op, "\t.area %s", bss_section_ptr);
++
++	/* Handle -mcode-bank */
++	if (code_bank_option != 0)
++		sprintf (default_code_bank_name, "%s", code_bank_option);
++
++	/* Handle -mabi-version or -mno-reg-args */
++	if (m6809_abi_version_ptr != 0)
++	{
++		if (!strcmp (m6809_abi_version_ptr, "stack"))
++			m6809_abi_version = M6809_ABI_VERSION_STACK;
++		else if (!strcmp (m6809_abi_version_ptr, "regs"))
++			m6809_abi_version = M6809_ABI_VERSION_REGS;
++		else if (!strcmp (m6809_abi_version_ptr, "bx"))
++			m6809_abi_version = M6809_ABI_VERSION_BX;
++		else if (!strcmp (m6809_abi_version_ptr, "latest"))
++			m6809_abi_version = M6809_ABI_VERSION_LATEST;
++		else
++			m6809_abi_version = atoi (m6809_abi_version_ptr);
++	}
++
++	/* The older -mno-reg-args option is deprecated, and treated
++	as -mabi=stack. */
++	if (!TARGET_REG_ARGS)
++   {
++      warning (WARNING_OPT "-mno-reg-args deprecated; use -mabi=stack instead.");
++      m6809_abi_version = M6809_ABI_VERSION_STACK;
++   }
++
++	/* -fexceptions is unsupported */
++	flag_exceptions = 0;
++	flag_non_call_exceptions = 0;
++	flag_unwind_tables = 0;
++}
++
++
++/**
++ * Output prefix that directs the assembler to use a direct-mode
++ * instruction if globally enabled, address is a symbol, and symbol
++ * has been marked as in direct page.  Also, never do this if
++ * using the indirect mode. */
++void
++print_direct_prefix (FILE * file, rtx addr)
++{
++	if (TARGET_DIRECT &&
++       (GET_CODE (addr) == SYMBOL_REF) && 
++       SYMBOL_REF_FLAG (addr) &&
++       check_direct_prefix_flag)
++   {
++      putc ('*', file);
++   }
++}
++
++
++/** Prints an operand (that is not an address) in assembly from RTL. */
++void
++print_operand (FILE * file, rtx x, int code)
++{
++	if (REG_P (x)) {
++		/* gcc currently allocates the entire 16-bit 'd' register
++		 * even when it only needs an 8-bit value.  So here it
++		 * is tricked into printing only the lower 8-bit 'b'
++		 * register into the assembly output.
++		 *
++		 * Eventually gcc should be modified to allocate a/b
++		 * independently and this hack can be removed.
++		 *
++		 * Occasionally, we may want to do an operation using
++		 * the 'a' register instead of 'b'; use the 'A' code
++		 * to specify that.
++		 */
++		if (code == 'A')
++			fputs ("a", file);
++		else if ((BYTE_MODE (x)) && (REGNO (x) == HARD_D_REGNUM))
++			fputs ("b", file);
++		else if (M_REG_P (x) && code == 'L')
++			/* Soft registers can be treated like memory and accessed
++			 * at a particular offset. TODO : handle 'W' */
++			fputs (reg_names[REGNO (x)+1], file);
++		else
++			fputs (reg_names[REGNO (x)], file);
++	}
++
++	else if (MEM_P (x)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (x));
++		if (code == 'L') {	/* LSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 1);
++		}
++		else if (code == 'M') { /* MSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 0);
++		}
++		else if (code == 'W') { /* least significant half of 32-bit */
++			x = adjust_address (x, HImode, 2);
++		}
++
++		pic_ok_for_addr_p = (code != 'C');
++		output_address (XEXP (x, 0));
++	}
++
++	else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) {
++		union { double d; int i[2]; } u;
++		u.i[0] = CONST_DOUBLE_LOW (x);
++		u.i[1] = CONST_DOUBLE_HIGH (x);
++		fprintf (file, "#%#9.9g", u.d);
++	}
++
++	else if (code == 'R') {
++		fprintf (file, "%s", 
++			m6809_get_regs_printable (INTVAL (x)));
++	}
++
++	else {
++		if (code == 'L') {	/* LSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, (INTVAL(x) & 0xff));
++		}
++		else if (code == 'M') {	/* MSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, ((INTVAL(x) >> 8) & 0xff));
++		}
++
++		putc ('#', file);
++		output_addr_const (file, x);
++	}
++}
++
++
++/** Prints an address operand to assembler from its RTL representation. */
++void
++print_operand_address (FILE *file, rtx addr)
++{
++	register rtx base = 0;
++	register rtx offset = 0;
++	int regno;
++	int indirect_flag = 0;
++
++	check_direct_prefix_flag = 0;
++
++	/*** check for indirect addressing ***/
++	if (MEM_P (addr)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (addr));
++		addr = XEXP (addr, 0);
++		if (pic_ok_for_addr_p)
++		{
++			indirect_flag = 1;
++			fprintf (file, "[");
++		}
++	}
++
++
++	switch (GET_CODE (addr)) {
++		case REG:
++			regno = REGNO (addr);
++			fprintf (file, ",%s", reg_names[regno]);
++			break;
++
++		case PRE_DEC:
++			regno = REGNO (XEXP (addr, 0));
++			fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++			fprintf (file, "%s", reg_names[regno]);
++			break;
++
++		case POST_INC:
++			regno = REGNO (XEXP (addr, 0));
++			fprintf (file, ",%s", reg_names[regno]);
++			fputs (((last_mem_size == 1) ? "+" : "++"), file);
++			break;
++
++		case PLUS:
++			base = XEXP (addr, 0);
++			if (MEM_P (base))
++				base = XEXP (base, 0);
++
++			offset = XEXP (addr, 1);
++			if (MEM_P (offset))
++				offset = XEXP (offset, 0);
++
++			if ((CONSTANT_ADDRESS_P (base)) && (CONSTANT_ADDRESS_P (offset))) {
++				if (!indirect_flag)
++					check_direct_prefix_flag = 1;
++				output_addr_const (file, base);
++				check_direct_prefix_flag = 0;
++				fputs ("+", file);
++				output_addr_const (file, offset);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (base)) && (A_REG_P (offset))) {
++				output_addr_const (file, base);
++				fprintf (file, ",%s", reg_names[REGNO (offset)]);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (offset)) && (A_REG_P (base))) {
++				output_addr_const (file, offset);
++				fprintf (file, ",%s", reg_names[REGNO (base)]);
++			}
++
++			/*** accumulator offset ***/
++			else if (((D_REG_P (offset)) || (Q_REG_P (offset)))
++			&& (A_REG_P (base))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (offset)], reg_names[REGNO (base)]);
++			}
++
++			else if (((D_REG_P (base)) || (Q_REG_P (base)))
++			&& (A_REG_P (offset))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (base)], reg_names[REGNO (offset)]);
++			}
++
++			else if (GET_CODE (base) == PRE_DEC) {
++				regno = REGNO (XEXP (base, 0));
++				fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++				fprintf (file, "%s", reg_names[regno]);
++			}
++
++			else
++				abort ();
++
++			break;
++
++   default:
++		/* Set this global before calling output_addr_const() */
++		if (!indirect_flag)
++			check_direct_prefix_flag = 1;
++
++		/* When printing a SYMBOL_REF in PIC mode, do not print the leading
++		 * '#' and follow it by ',pcr' to enable relative addressing. */
++		if (flag_pic && pic_ok_for_addr_p && GET_CODE (addr) == SYMBOL_REF)
++		{
++			ASM_OUTPUT_SYMBOL_REF (file, addr);
++			fputs (",pcr", file);
++			pic_ok_for_addr_p = 1;
++		}
++		else
++		{
++      	output_addr_const (file, addr);
++		}
++
++		check_direct_prefix_flag = 0;
++      break;
++	}
++
++	if (indirect_flag)
++		fprintf (file, "]");
++}
++
++/*-------------------------------------------------------------------
++    Update the CC Status
++---------------------------------------------------------------------
++   Set the cc_status for the results of an insn whose pattern is EXP.
++   We assume that jumps don't affect the condition codes.
++   All else, clobbers the condition codes, by assumption.
++
++   We assume that ALL add, minus, etc. instructions effect the condition
++   codes.
++-------------------------------------------------------------------*/
++void
++notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
++{
++	int src_code;
++	int dst_code;
++
++	/*** recognize SET insn's ***/
++	if (GET_CODE (exp) == SET)
++	{
++		src_code = GET_CODE (SET_SRC (exp));
++		dst_code = GET_CODE (SET_DEST (exp));
++
++		/* Jumps do not alter the cc's.  */
++		if (SET_DEST (exp) == pc_rtx)
++			return;
++
++		/* Moving one register into another register (tfr):
++		Doesn't alter the cc's.  */
++		if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp))))
++			return;
++
++		/* Moving memory into a register (load): Sets cc's. */
++		if (REG_P (SET_DEST (exp)) && src_code == MEM) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Moving register into memory (store): Sets cc's. */
++		if (dst_code == MEM && REG_P (SET_SRC (exp))) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Function calls clobber the cc's.  */
++		else if (GET_CODE (SET_SRC (exp)) == CALL) {
++			CC_STATUS_INIT;
++			return;
++		}
++
++		/* Tests and compares set the cc's in predictable ways.  */
++		else if (SET_DEST (exp) == cc0_rtx)
++		{
++			cc_status.flags = 0;
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			return;
++		}
++
++		else if (A_REG_P (SET_DEST (exp)))
++		{
++			CC_STATUS_INIT;
++			return;
++		}
++
++		else
++		{
++			/* Certain instructions affect the condition codes. */
++			switch (src_code)
++			{
++				case PLUS:
++				case MINUS:
++				case NEG:
++				case ASHIFT:
++					/* These instructions set the condition codes,
++					 * and may modify the V bit. */
++					cc_status.flags |= CC_NO_OVERFLOW;
++					/* FALLTHRU */
++
++				case AND:
++				case IOR:
++				case XOR:
++				case ASHIFTRT:
++				case LSHIFTRT:
++					/* These instructions set the condition codes,
++					 * but cannot overflow (V=0). */
++					cc_status.value1 = SET_SRC (exp);
++					cc_status.value2 = SET_DEST (exp);
++					break;
++
++				default:
++					/* Everything else is clobbered */
++					CC_STATUS_INIT;
++			}
++			return;
++		}
++	} /* SET */
++
++	else if (GET_CODE (exp) == PARALLEL
++		&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
++	{
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
++			return;
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
++		{
++			CC_STATUS_INIT;
++			cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
++			return;
++		}
++	}
++
++	/*** default action if we haven't recognized something
++	and returned earlier ***/
++	CC_STATUS_INIT;
++}
++
++
++/** Returns nonzero if the expression EXP can be implemented using one
++ * of the 6809's single operand instructions. */
++int
++m6809_single_operand_operator (rtx exp)
++{
++	rtx op1;
++	HOST_WIDE_INT val;
++	enum rtx_code code;
++
++	debug_rtx(exp);
++
++	code = GET_CODE (exp);
++
++	/* Unary operators always qualify */
++	switch (code)
++	{
++		case NEG:
++		case NOT:
++			return 1;
++
++		default:
++			break;
++	}
++
++	/* Binary operators can only qualify if the second
++	 * argument is a CONST_INT of certain value. */
++	op1 = XEXP (exp, 1);
++	if (GET_CODE (op1) != CONST_INT)
++		return 0;
++	val = INTVAL (op1);
++	switch (code)
++	{
++		case PLUS:
++		case MINUS:
++			if (val == -1 || val == 1)
++				return 1;
++			break;
++
++		case ASHIFT:
++		case ASHIFTRT:
++		case LSHIFTRT:
++		case ROTATE:
++		case ROTATERT:
++			if (val == 1)
++				return 1;
++			break;
++
++		default:
++			break;
++	}
++
++	return 0;
++}
++
++
++/** Return a bitarray of the hard registers which are used by a function. */
++unsigned int
++m6809_get_live_regs (void)
++{
++	unsigned int regs = 0;
++	int regno;
++
++	if (frame_pointer_needed)
++		regs |= (1 << HARD_FRAME_POINTER_REGNUM);
++
++	for (regno = HARD_X_REGNUM; regno <= HARD_U_REGNUM; regno++)
++		if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
++			regs |= (1 << regno);
++
++	return regs;
++}
++
++
++/** Return a printable version of a list of hard registers, suitable
++ * for use in a PSHx or PULx insn. */
++const char *
++m6809_get_regs_printable (unsigned int regs)
++{
++	static char list[64];
++	char *listp = list;
++	unsigned int regno;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++		if ((regs & (1 << regno)) && !S_REGNO_P (regno))
++			listp += sprintf (listp,
++				(listp == list) ? "%s" : ",%s", reg_names[regno]);
++
++	return list;
++}
++
++
++/** Return the total number of bytes covered by a set of hard registers. */
++unsigned int
++m6809_get_regs_size (unsigned int regs)
++{
++	unsigned int regno;
++	unsigned int size = 0;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++	{
++		/* Only count register in the given register set */
++		if (REGSET_CONTAINS_P (regno, regs))
++		{
++			/* Add 1 or 2 byte, depending on the size of the register.
++			 * Since 'D' may be in both sets, check for WORD_REGSET first. */
++			if (REGSET_CONTAINS_P(regno, WORD_REGSET))
++				size += 2;
++			else if (REGSET_CONTAINS_P(regno, BYTE_REGSET))
++				size++;
++		}
++	}
++	return size;
++}
++
++
++/* Given the target of call instruction in X,
++ * return the tree node that contains the function declaration for
++ * that target.
++ *
++ * If the rtx or the tree do not appear valid for any reason,
++ * then return NULL_TREE.
++ */
++static tree call_target_decl (rtx x)
++{
++   tree decl;
++
++	/* Make sure the target is really a MEM. */
++	if (!x || !MEM_P (x))
++		return NULL_TREE;
++
++	/* Make sure the address is a SYMBOL_REF. */
++	x = XEXP (x, 0);
++	if (!x || (GET_CODE (x) != SYMBOL_REF))
++		return NULL_TREE;
++
++	/* Get the declaration of this symbol */
++	decl = SYMBOL_REF_DECL (x);
++
++	/* Make sure the declaration is really a function. */
++	if (!decl || (TREE_CODE(decl) != FUNCTION_DECL))
++		return NULL_TREE;
++
++   return decl;
++}
++
++
++/** Returns nonzero if a function, whose declaration is in DECL,
++ * was declared to have the attribute given by ATTR_NAME. */
++int
++m6809_function_has_type_attr_p (tree decl, const char *attr_name)
++{
++	tree type;
++
++	type = TREE_TYPE (decl);
++	return lookup_attribute (attr_name, TYPE_ATTRIBUTES (type)) != NULL;
++}
++
++
++
++/** Returns nonzero if the current function was declared to have the
++ * attribute given by ATTR_NAME. */
++int
++m6809_current_function_has_type_attr_p (const char *attr_name)
++{
++	return m6809_function_has_type_attr_p (current_function_decl, attr_name);
++}
++
++
++/** Return nonzero if the current function has no return value. */
++int
++m6809_current_function_is_void (void)
++{
++   return (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
++}
++
++
++/** Get the value of a declaration's 'bank', as set by the 'bank'
++ * attribute.  If no bank was declared, it returns NULL by default. */
++const char *
++m6809_get_decl_bank (tree decl)
++{
++	tree attr;
++
++	/* Lookup the 'bank' attribute.  If it does not exist, then
++	 * return NULL */
++	attr = lookup_attribute ("bank", DECL_ATTRIBUTES (decl));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* Make sure it has a value assigned to it */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "banked function did not declare a bank number");
++		return NULL;
++	}
++
++	/* Return the bank name */
++	attr = TREE_VALUE (attr);
++	return TREE_STRING_POINTER (attr);
++}
++
++
++void
++m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl)
++{
++	/* Check the function declaration for special properties.
++	 *
++	 * If the function was declare with __attribute__((bank)), output
++	 * assembler definitions to force the function to go into the named
++	 * bank.
++	 */
++	const char *bank_name = m6809_get_decl_bank (decl);
++	if (bank_name != NULL)
++	{
++		/* Declare __self_bank as a local assembler value that denotes
++		 * which bank the current function is in.  This is required only
++		 * when the bank actually changes. */
++		if (strcmp (bank_name, current_bank_name))
++		{
++			fprintf (asm_out_file, "__self_bank\t.equ %s\n", bank_name);
++			strcpy (current_bank_name, bank_name);
++		}
++
++		/* Declare a global assembler value that denotes which bank the
++		 * named function is in. */
++		fprintf (asm_out_file, "__%s_bank\t.gblequ %s\n", name, bank_name);
++
++		/* Force the current function into a new area */
++		fprintf (asm_out_file, "\t.bank bank_%s (FSFX=_%s)\n",
++			bank_name, bank_name);
++		fprintf (asm_out_file, "\t.area bank_%s (BANK=bank_%s)\n",
++			bank_name, bank_name);
++	}
++
++	/* Emit the label for the function's name */
++	ASM_OUTPUT_LABEL (asm_out_file, name);
++}
++
++#if 0
++/**
++ * Handle pragmas.  Note that only the last branch pragma seen in the 
++ * source has any affect on code generation.  
++ */
++
++#define BAD_PRAGMA(msgid, arg) \
++	do { warning (WARNING_OPT msgid, arg); return -1; } while (0)
++
++static int
++pragma_parse (const char *name, tree *sect)
++{
++  tree s, x;
++
++  if (pragma_lex (&x) != CPP_OPEN_PAREN)
++    BAD_PRAGMA ("missing '(' after '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&s) != CPP_STRING)
++    BAD_PRAGMA ("missing section name in '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
++    BAD_PRAGMA ("missing ')' for '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_EOF)
++    warning (WARNING_OPT "junk at end of '#pragma %s'", name);
++
++  *sect = s;
++  return 0;
++}
++
++
++/*
++ * Handle #pragma section.
++ * This is deprecated; code should use __attribute__(section("name"))
++ * instead.
++ */
++void pragma_section (cpp_reader *pfile ATTRIBUTE_UNUSED)
++{
++	tree sect;
++
++	if (pragma_parse ("section", &sect))
++		return;
++
++	snprintf (code_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++	snprintf (data_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++
++	/* Mark a flag that sections have changed.  Upon emitting another
++	 * declaration, the new .area directive will be written. */
++	section_changed++;
++}
++#endif
++
++/**
++ * Check a `double' value for validity for a particular machine mode.
++ * Called by the CHECK_FLOAT_VALUE() machine-dependent macro.
++ */
++int
++check_float_value (enum machine_mode mode, double *d, int overflow)
++{
++	if (mode == SFmode) {
++		if (*d > 1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = 1.7014117331926443e+38;
++		}
++		else if (*d < -1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = -1.7014117331926443e+38;
++		}
++		else if ((*d > 0) && (*d < 2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++		else if ((*d < 0) && (*d > -2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++	}
++	return overflow;
++}
++
++
++
++/** Declare that the target supports named output sections. */
++bool m6809_have_named_section = (bool)1;
++
++
++/** Write to the assembler file a directive to place
++ * subsequent objects to a different section in the
++ * object file.  ASxxxx uses the "area" directive for
++ * this purpose.  It does not however support generalized
++ * alignment, and can only place items on an odd/even
++ * boundary. */
++void
++m6809_asm_named_section (
++	const char *name, 
++	unsigned int flags ATTRIBUTE_UNUSED,
++	tree decl)
++{
++	fprintf (asm_out_file, "\t.area\t%s\n", name);
++}
++
++
++enum reg_class
++m6809_preferred_reload_class (rtx x, enum reg_class regclass)
++{
++	/* Check cases based on type code of rtx */
++	switch (GET_CODE(x))
++	{
++		/*
++		 * Observation, 2015-07-19, William Astle
++		 *
++		 * The original comparison for range for 16 bits was wrong, adding 0x80
++		 * instead of 0x8000. Replaced both 8 bit and 16 bit comparisions with
++		 * a more straight forward range comparison - excessive cleverness isn't
++		 * really required here.
++		 */    
++		case CONST_INT:
++		   /* Constants that can fit into 1 byte should be
++			 * loaded into a Q_REGS reg */
++			if ((INTVAL(x) >= -128 && INTVAL(x) <= 127) &&
++//			if (((unsigned) (INTVAL(x) + 0x80) < 0x100) && 
++  				 (regclass > A_REGS))
++      		return Q_REGS;
++
++			/* 16-bit constants should be loaded into A_REGS
++			 * when possible.  gcc may already require A_REGS
++			 * or D_REGS for certain types of instructions.
++			 * This case applies mostly to simple copy operations
++			 * to/from memory when any register will do, but
++			 * it's best to avoid using D register since it is
++			 * needed for other things.
++			 */
++			else if ((INTVAL(x) >= -32768 && INTVAL(x) <= 32767) &&
++//			else if (((unsigned) (INTVAL(x) + 0x80) < 0x10000) &&
++  				 (regclass > A_REGS))
++      		return A_REGS;
++			break;
++
++		case SYMBOL_REF:
++		case LABEL_REF:
++			/* Addresses should always be loaded into A_REGS */
++			if (regclass >= A_REGS)
++				return (A_REGS);
++
++		default:
++			break;
++	}
++
++	/* Check cases based on mode of rtx */
++   if ((GET_MODE(x) == QImode) && (regclass != A_REGS))
++      return Q_REGS;
++
++	/* Default: return whatever class reload suggested */
++   return regclass;
++}
++
++
++/**
++ * Check a new declaration for the "section" attribute.
++ * If it exists, and the target section is "direct", then mark
++ * the declaration (in RTL) to indicate special treatment.
++ * When the variable is referenced later, we test for this flag
++ * and can emit special asm text to force the assembler to use
++ * short instructions.
++ */
++static void
++m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED)
++{
++   tree attr, id;
++   const char *name;
++   const char *decl_name;
++
++   /* We only care about variable declarations, not functions */
++   if (TREE_CODE (decl) != VAR_DECL)
++      return;
++
++	/* For debugging purposes only; grab the decl's name */
++   decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
++
++	/* Give up if the decl doesn't have any RTL */
++   if (!DECL_RTL (decl))
++      return;
++
++	/* See if it has a section attribute */
++   attr = lookup_attribute ("section", DECL_ATTRIBUTES (decl));
++   if (!attr)
++      return;
++
++	/* See if the section attribute has a value */
++   id = TREE_VALUE (TREE_VALUE (attr));
++   if (!id)
++      return;
++   name = TREE_STRING_POINTER (id);
++   if (!name)
++      return;
++
++	/* See if the value is 'direct'.  If so, mark it. */
++   if (!strcmp (name, "direct"))
++      SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
++}
++
++
++/**
++ * Output code to perform a complex shift, for which there is no
++ * direct support in the instruction set.
++ *
++ * shift1 is an instruction pattern for performing a 1-bit modification.
++ * This code wraps that pattern in a loop to perform the shift N times,
++ * where N is given by the address register in operands[2].
++ *
++ * To support 16-bit shifts, shift2 can also be provided: it is
++ * a second instruction to be included in the loop.  8-bit shift
++ * insns will pass NULL here.
++ *
++ * The insn length of shift1/shift2 is assumed to be 1 byte,
++ * which works in all of the cases it is needed so far.
++ */
++static void
++m6809_gen_register_shift (
++		rtx *operands,
++		const char *shift1,
++		const char *shift2 )
++{
++	char beq_pattern[32];
++   char bra_pattern[32];
++
++	int shiftlen = (shift1 && shift2) ? 2 : 1;
++	int cmplen = (REGNO (operands[2]) == HARD_X_REGNUM) ? 3 : 4;
++
++	int beq_offset = 2 + shiftlen + 2;
++	int bra_offset = shiftlen + 2 + cmplen + 2;
++
++	sprintf (beq_pattern, "beq\t.+%d", beq_offset);
++	sprintf (bra_pattern, "bra\t.-%d", bra_offset);
++
++	output_asm_insn ("pshs\t%2", operands);
++	output_asm_insn ("lea%2\t-1,%2", operands);
++   output_asm_insn ("cmp%2\t#-1", operands);
++   output_asm_insn (beq_pattern, operands);
++	if (shift1)
++		output_asm_insn (shift1, operands);
++	if (shift2)
++		output_asm_insn (shift2, operands);
++	output_asm_insn (bra_pattern, operands);
++	output_asm_insn ("puls\t%2", operands);
++}
++
++
++/** Generate RTL for the upper 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_high (rtx r)
++{
++   unsigned char v = (INTVAL (r) >> 8) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL for the lower 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_low (rtx r)
++{
++   unsigned char v = INTVAL (r) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL to allocate/free bytes on the stack.
++ * CODE is given as MINUS when allocating and PLUS when freeing,
++ * to match the semantics of a downward-growing stack.  SIZE
++ * is always given as a positive integer.
++ */
++static rtx
++gen_rtx_stack_adjust (enum rtx_code code, int size)
++{
++	if (size <= 0)
++		return NULL_RTX;
++
++	if (code == MINUS)
++		size = -size;
++
++	return gen_rtx_SET (Pmode, stack_pointer_rtx, 
++		gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++			gen_int_mode (size, HImode)));
++}
++
++
++/** Generate RTL to push/pop a set of registers. */
++rtx
++gen_rtx_register_pushpop (int op, int regs)
++{
++	rtx nregs = gen_int_mode (regs, QImode);
++	
++	if (op == UNSPEC_PUSH_RS)
++		return gen_register_push (nregs);
++	else
++		return gen_register_pop (nregs);
++}
++
++
++/* Given a register set REGS, where the bit positions correspond to
++ * hard register numbers, return another bitmask that represents the
++ * order in which those registers would be pushed/popped.
++ * Registers that are pushed first have higher bit positions.
++ * The pop order is just the reverse bitmask.
++ * These values are the same as the bitmasks actually used in the
++ * machine instructions. */
++static unsigned int
++register_push_order (int regs)
++{
++	unsigned int order = 0;
++
++	if (REGSET_CONTAINS_P (HARD_PC_REGNUM, regs))
++		order |= 0x80;
++	if (REGSET_CONTAINS_P (HARD_U_REGNUM, regs))
++		order |= 0x40;
++	if (REGSET_CONTAINS_P (HARD_Y_REGNUM, regs))
++		order |= 0x20;
++	if (REGSET_CONTAINS_P (HARD_X_REGNUM, regs))
++		order |= 0x10;
++	if (REGSET_CONTAINS_P (HARD_DP_REGNUM, regs))
++		order |= 0x8;
++	if (REGSET_CONTAINS_P (HARD_B_REGNUM, regs))
++		order |= 0x4;
++	if (REGSET_CONTAINS_P (HARD_A_REGNUM, regs))
++		order |= 0x2;
++	if (REGSET_CONTAINS_P (HARD_CC_REGNUM, regs))
++		order |= 0x1;
++
++	if (REGSET_CONTAINS_P (HARD_D_REGNUM, regs))
++		order |= (0x4 | 0x2);
++	return order;
++}
++
++
++/* Returns nonzero if two consecutive push or pop instructions,
++ * as determined by the OP, can be merged into a single instruction.
++ * The first instruction in the sequence pushes/pops REGS1; the
++ * second applies to REGS2.
++ *
++ * If true, the resulting instruction can use (regs1 | regs2)
++ * safely.
++ */
++int
++m6809_can_merge_pushpop_p (int op, int regs1, int regs2)
++{
++	/* Register sets must not overlap */
++	if (regs1 & regs2)
++		return 0;
++
++	if (op == UNSPEC_PUSH_RS)
++		return (register_push_order (regs1) > register_push_order (regs2));
++	else if (op == UNSPEC_POP_RS)
++		return (register_push_order (regs1) < register_push_order (regs2));
++	else
++		return 0;
++}
++
++
++/** Emit instructions for making a library call.
++ * MODE is the mode of the operation.
++ * NAME is the library function name.
++ * OPERANDS is the rtx array provided by the recognizer.
++ * COUNT is the number of input operands to the call, and
++ * should be 1 for a unary op or 2 for a binary op.
++ */
++void
++emit_libcall_insns (enum machine_mode mode, 
++	const char *name, 
++	rtx *operands,
++	int count)
++{
++	/* Generate an rtx for the call target. */
++	rtx symbol = gen_rtx_SYMBOL_REF (Pmode, name);
++
++	/* Emit the library call.  Slightly different based
++	on the number of operands */
++	if (count == 2)
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			2, operands[1], mode, operands[2], mode);
++	else
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			1, operands[1], mode);
++
++	/* The library call is expected to put its result
++	in LIBCALL_VALUE, so need to copy it into the destination. */
++	emit_move_insn (operands[0], LIBCALL_VALUE(mode));
++}
++
++
++/**
++ * A small helper function that writes out a single branch instruction.
++ * OPCODE is the short name, e.g. "ble".
++ * OPERANDS has the rtx for the target label.
++ * LONG_P is nonzero if we are emitting a long branch, and need to
++ * prepend an 'l' to the opcode name.
++ */
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p)
++{
++	char pattern[64];
++	sprintf (pattern, "%s%s\t%%l0", long_p ? "l" : "", opcode);
++	output_asm_insn (pattern, operands);
++}
++
++/**
++ * Output a branch/conditional branch insn of the proper
++ * length.  code identifies the particular branch insn.
++ * operands holds the branch target in operands[0].
++ * length says what the size of this insn should be.
++ * Based on the length, we know whether it should be a
++ * short (8-bit) or long (16-bit) branch.
++ */
++const char *
++output_branch_insn (enum rtx_code code, rtx *operands, int length)
++{
++	int shortform; 
++
++	/* Decide whether or not to use the long or short form.
++	 * Calculate automatically based on insn lengths. */
++   shortform = ((length > 2) ? 0 : 1);
++
++	/* Determine the proper opcode.
++	 * Use the short (2-byte) opcode if the target is within
++	 * reach.  Otherwise, use jmp (3-byte opcode), unless
++	 * compiling with -fpic, in which case we'll need to use
++	 * lbra (4-byte opcode).
++	 */
++	switch (code)
++	{
++		case LABEL_REF: 
++			if (shortform)
++				output_branch_insn1 ("bra", operands, 0);
++			else if (flag_pic)
++				output_branch_insn1 ("bra", operands, 1);
++			else
++				output_branch_insn1 ("jmp", operands, 0);
++			break;
++		case EQ:
++			output_branch_insn1 ("beq", operands, !shortform);
++			break;
++		case NE:
++			output_branch_insn1 ("bne", operands, !shortform);
++			break;
++		case GT:
++			output_branch_insn1 ("bgt", operands, !shortform);
++			break;
++		case GTU:
++			output_branch_insn1 ("bhi", operands, !shortform);
++			break;
++		case LT:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("blt", operands, !shortform);
++			}
++			break;
++		case LTU:
++			output_branch_insn1 ("blo", operands, !shortform);
++			break;
++		case GE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bpl", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("bge", operands, !shortform);
++			}
++			break;
++		case GEU:
++			output_branch_insn1 ("bhs", operands, !shortform);
++			break;
++		case LE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++				output_branch_insn1 ("beq", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("ble", operands, !shortform);
++			}
++			break;
++		case LEU:
++			output_branch_insn1 ("bls", operands, !shortform);
++			break;
++		default:
++			abort();
++			break;
++	}
++	return "";
++}
++
++
++/** Returns the "cost" of an RTL expression.
++ * In general, the expression "COSTS_N_INSNS(1)" is used to represent
++ * the cost of a fast 8-bit arithmetic instruction that operates on
++ * a reg/mem or a reg/immed.  Other costs are relative to this.
++ *
++ * Notes:
++ * - The cost of a REG is always zero; this cannot be changed.
++ *
++ * - On the 6809, instructions on two registers will nearly always take
++ *   longer than those that operate on a register and a constant/memory,
++ *   because of the way the instruction set is structured.
++ *
++ * TODO: multiply HImode by 2 should be done via shifts, instead of add.
++ */
++static bool
++m6809_rtx_costs (rtx X, int code, int outer_code ATTRIBUTE_UNUSED,
++	int *total, bool speed)
++{
++	int has_const_arg = 0;
++	HOST_WIDE_INT const_arg;
++	enum machine_mode mode;
++	int nargs = 1;
++	rtx op0, op1;
++
++	/* Data RTXs return a value between 0-3, depending on complexity.
++	All of these are less than COSTS_N_INSNS(1). */
++	switch (code)
++	{
++		case CC0:
++		case PC:
++			*total = 0;
++			return true;
++
++ 		case CONST_INT:
++    		if (X == const0_rtx)
++			{
++				*total = 0;
++				return true;
++			}
++			else if ((unsigned) INTVAL (X) < 077) 
++			{
++				*total = 1;
++				return true;
++			}
++			else
++			{
++				*total = 2;
++				return true;
++			}
++
++ 		case LABEL_REF: case CONST:
++   		*total = 2;
++			return true;
++
++ 		case SYMBOL_REF:
++			/* References to memory are made cheaper if they have
++			 * the 'direct' mode attribute set */
++			*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++			return true;
++
++		case MEM:
++			/* See what form of address was given */
++			X = XEXP (X, 0);
++			switch (GET_CODE (X))
++			{
++ 				case SYMBOL_REF:
++					*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++					break;
++
++				case CONST_INT:
++					*total = 2;
++					break;
++
++				case MEM:
++					*total = COSTS_N_INSNS (1) + 2;
++					break;
++
++				default:
++					break;
++			}
++			return true;
++
++ 		case CONST_DOUBLE:
++			/* TODO : not sure about this value. */
++   		*total = 3;
++			return true;
++
++		default:
++			break;
++	}
++
++	/* Decode the rtx */
++	mode = GET_MODE (X);
++	op0 = XEXP (X, 0);
++	op1 = XEXP (X, 1);
++
++	/* We don't implement anything in SImode or greater. */
++	if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (SImode))
++	{
++		*total = COSTS_N_INSNS (100);
++		return true;
++	}
++
++	/* Figure out if there is a constant argument, and its value. */
++	if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
++		|| GET_RTX_CLASS (code) == RTX_COMM_ARITH)
++	{
++		nargs = 2;
++		if (GET_CODE (op1) == CONST_INT)
++		{
++			has_const_arg = 1;
++			const_arg = INTVAL (op1);
++		}
++	}
++
++	/* Penalize a reg/reg operation by adding MEMORY_MOVE_COST,
++	 * Ignore soft registers, since these are really in memory.
++	 *
++	 * TODO: penalize HImode reg/reg for most operations, except maybe
++	 * additions since index registers allow for that.
++	 *
++	 * TODO: shifts by constant N do not always require N instructions;
++	 * some of this can be done cheaper.  The number of actual insns can be
++	 * predicted well.
++	 */
++	if (nargs == 2 && REAL_REG_P (op0) && REAL_REG_P (op1))
++	{
++		*total = MEMORY_MOVE_COST (mode, Q_REGS, 0);
++	}
++	else
++	{
++		*total = 0;
++	}
++
++	/* Operator RTXs are counted as COSTS_N_INSNS(N), where N is
++	the estimated number of actual machine instructions needed to
++	perform the computation.  Some small adjustments are made since
++	some "instructions" are more complex than others. */
++	switch (code)
++	{
++		case PLUS: case MINUS: case COMPARE:
++			/* 6809 handles these natively in QImode, and in HImode as long
++			 * as operand 1 is constant. */
++			if (mode == QImode || (mode == HImode && has_const_arg))
++				*total += COSTS_N_INSNS (1);
++			else 
++				*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
++
++			/* -1, 0, and 1 can be done using inherent instructions
++			 * for PLUS and MINUS in QImode, so don't add extra cost. */
++  			if (has_const_arg
++				&& (mode == QImode || mode == HImode)
++				&& (const_arg == -1 || const_arg == 0 || const_arg == 1)
++				&& (code == PLUS || code == MINUS))
++			{
++				return true;
++			}
++			break;
++
++		case AND: case IOR: case XOR:
++		case NEG: case NOT:
++			/* 6809 handles these natively in QImode, but requires
++			 * splitting in HImode.   Treat these as 2 insns. */
++			*total += COSTS_N_INSNS (1) * GET_MODE_SIZE (mode);
++			break;
++
++  		case ASHIFT: case ASHIFTRT: case LSHIFTRT:
++  		case ROTATE: case ROTATERT:
++			/* 6809 can do shift/rotates of a QImode by a constant in
++			 * 1 insn times the shift count, or in HImode by a constant 
++			 * by splitting to 2 insns.
++			 *
++			 * Shift by a nonconstant will take significantly longer
++			 * than any of these. */
++  			if (has_const_arg)
++			{
++				const_arg %= (GET_MODE_SIZE (mode) * 8);
++				if (const_arg == 0)
++				{
++					*total += COSTS_N_INSNS(1);
++					return true;
++				}
++
++				/* HImode shifts greater than 8 get optimized due
++				 * to register transfer from b to a; this cuts down the
++				 * cost. */
++				if (const_arg >= 8)
++				{
++					*total += COSTS_N_INSNS (1);
++					const_arg -= 8;
++				}
++
++				/* The computed cost is 'const_arg' 1-bit shifts, doubled
++				if in HImode, minus the cost of the constant itself which
++				will be added in later but really shouldn't be. */
++				*total += COSTS_N_INSNS (const_arg) * GET_MODE_SIZE (mode) - 1;
++				return true;
++			}
++			else
++			{
++				/* It may take up to 7 iterations of about 6-7 real
++				 * instructions, so make this expensive. */
++				*total += COSTS_N_INSNS (50);
++			}
++  			break;
++
++		case MULT:
++ 		{
++ 			/* Multiply is cheap when both arguments are 8-bits.  They
++ 			could be QImode, or QImode widened to HImode, or a constant
++ 			that fits into 8-bits.  As long as both operands qualify,
++ 			we can use a single mul instruction.
++  
++ 			Assume that fast multiply can be used, and change this if we find
++ 			differently... */
++ 			int ok_for_qihi3 = 1;
++  
++ 			/* Check the first operand */	
++ 			switch (GET_MODE (op0))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++ 					if (GET_CODE (op0) != SIGN_EXTEND && GET_CODE (op0) != ZERO_EXTEND)
++  						ok_for_qihi3 = 0;
++ 					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++  			}
++ 
++			/* Likewise, check the second operand.  This is where constants may appear. */
++ 			switch (GET_MODE (op1))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++					if (GET_CODE (op1) != SIGN_EXTEND && GET_CODE (op1) != ZERO_EXTEND)
++ 						ok_for_qihi3 = 0;
++ 					break;
++ 				case VOIDmode:
++					if (!CONST_OK_FOR_LETTER_P (const_arg, 'K'))
++ 						ok_for_qihi3 = 0;
++					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++ 			}
++ 
++ 			/* Fast multiply takes about 4 times as many cycles as a normal
++ 			arithmetic operation.  Otherwise, it will take an expensive libcall. */
++ 			if (ok_for_qihi3)
++ 				*total += COSTS_N_INSNS (4);
++ 			else
++ 				*total = COSTS_N_INSNS (50);
++  	  		break;
++ 		}
++
++		case DIV: case UDIV: case MOD: case UMOD:
++			/* These all require more expensive libcalls. */
++			*total += COSTS_N_INSNS (100);
++  			break;
++
++		/* TODO : TRUNCATE, SIGN_EXTEND, and ZERO_EXTEND */
++
++		/* These can normally be done with autoincrement, etc., so
++		 * don't charge for them. */
++		case PRE_DEC:
++		case PRE_INC:
++		case POST_DEC:
++		case POST_INC:
++			break;
++
++		default:
++			break;
++	}
++
++	/* Always return false, and let the caller gather the costs
++	 * of the operands */
++	return false;
++}
++
++
++static tree
++m6809_handle_fntype_attribute (tree *node, tree name,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs)
++{
++	if (TREE_CODE (*node) != FUNCTION_TYPE)
++	{
++		warning (WARNING_OPT "'%s' only valid for functions", 
++			IDENTIFIER_POINTER (name));
++		*no_add_attrs = TRUE;
++	}
++
++	return NULL_TREE;
++}
++
++
++static tree
++m6809_handle_data_type_attribute (tree *node ATTRIBUTE_UNUSED,
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED)
++{
++	return NULL_TREE;
++}
++
++
++
++static tree
++m6809_handle_default_attribute (tree *node ATTRIBUTE_UNUSED, 
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED )
++{
++	return NULL_TREE;
++}
++
++
++/* Table of valid machine attributes */
++const struct attribute_spec m6809_attribute_table[] = { /*
++{ name,        min, max, decl,  type, fntype, handler } */
++{ "interrupt", 0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "naked",     0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "far",       0,   1,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "bank",      0,   1,   true,  false, false, m6809_handle_default_attribute },
++{ "boolean",   0,   0,   false, true,  false, m6809_handle_data_type_attribute },
++{ NULL,        0,   0,   false, true,  false, NULL },
++};
++
++
++/** Initialize builtin routines for the 6809. */
++void
++m6809_init_builtins (void)
++{
++	/* Create type trees for each function signature required.
++	 *
++	 * void_ftype_void = void f(void)
++	 * void_ftype_uchar = void f(unsigned char)
++	 * uchar_ftype_uchar2 = unsigned char f (unsigned char, unsigned char)
++	 */
++	tree void_ftype_void = 
++		build_function_type (void_type_node, void_list_node);
++
++	tree void_ftype_uchar =
++		build_function_type (void_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node));
++
++	tree uchar_ftype_uchar2 =
++		build_function_type (unsigned_char_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, 
++				tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node)));
++
++	/* Register each builtin function. */
++	add_builtin_function ("__builtin_swi", void_ftype_void,
++		M6809_SWI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi2", void_ftype_void,
++		M6809_SWI2, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi3", void_ftype_void,
++		M6809_SWI3, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_cwai", void_ftype_uchar,
++		M6809_CWAI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sync", void_ftype_void,
++		M6809_SYNC, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_nop", void_ftype_void,
++		M6809_NOP, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_blockage", void_ftype_void,
++		M6809_BLOCKAGE, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_decimal", uchar_ftype_uchar2,
++		M6809_ADD_DECIMAL, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_carry", uchar_ftype_uchar2,
++		M6809_ADD_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sub_carry", uchar_ftype_uchar2,
++		M6809_SUB_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++}
++
++
++/** Used by m6809_expand_builtin, given a tree ARGLIST which
++ * refers to the operands of a builtin call, return an rtx
++ * that represents the nth operand, as denoted by OPNUM, which
++ * is a zero-based integer.  MODE gives the expected mode
++ * of the operand.
++ *
++ * This rtx is suitable for use in the emitted RTL for the
++ * builtin instruction. */
++rtx
++m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum)
++{
++	tree arg;
++	rtx r;
++
++	arg = CALL_EXPR_ARG (arglist, opnum);
++
++	/* Convert the tree to RTL */
++	r = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
++	if (r == NULL_RTX)
++		return NULL_RTX;
++	return r;
++}
++
++
++/** Expand a builtin that was registered in init_builtins into
++ * RTL.  */
++rtx
++m6809_expand_builtin (tree exp, 
++	rtx target, 
++	rtx subtarget ATTRIBUTE_UNUSED,
++	enum machine_mode mode ATTRIBUTE_UNUSED,
++	int ignore ATTRIBUTE_UNUSED )
++{
++   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
++	tree arglist = exp;
++	unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
++	rtx r0, r1;
++
++	switch (fcode)
++	{
++		case M6809_SWI:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 1);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI2:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 2);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI3:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 3);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_CWAI:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			emit_insn (target = gen_m6809_cwai (r0));
++			return target;
++
++		case M6809_SYNC:
++			emit_insn (target = gen_m6809_sync ());
++			return target;
++
++		case M6809_ADD_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_SUB_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_subqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_NOP:
++			emit_insn (target = gen_nop ());
++			return target;
++
++		case M6809_BLOCKAGE:
++			emit_insn (target = gen_blockage ());
++			return target;
++
++		case M6809_ADD_DECIMAL:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_decimal (target, r0, r1));
++			return target;
++
++		default:
++			warning (WARNING_OPT "unknown builtin expansion ignored");
++			return NULL_RTX;
++	}
++}
++
++
++
++/* Returns nonzero if 'x' represents a function that was declared
++ * as __noreturn__. */
++int
++noreturn_functionp (rtx x)
++{
++	tree decl = call_target_decl (x);
++
++	if (decl == NULL_TREE)
++		return 0;
++	else
++		return TREE_THIS_VOLATILE (decl);
++}
++
++
++const char *
++far_function_type_p (tree type)
++{
++	tree attr;
++	const char *page;
++
++	/* Return whether or not this decl has the far attribute */
++	attr = lookup_attribute ("far", TYPE_ATTRIBUTES (type));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* If it is far, check for a value */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "far code page not specified, using local value");
++		return far_code_page;
++	}
++
++	/* We have a TREE_LIST of attribute values, get the first one.
++	 * It should be an INTEGER_CST. */
++	attr = TREE_VALUE (attr);
++	page = TREE_STRING_POINTER (attr);
++	return page;
++}
++
++
++/* For a far function, returns the identifier that states which page
++ * it resides in.  Otherwise, returns NULL for ordinary functions. */
++const char *
++far_functionp (rtx x)
++{
++	tree decl, decl_type;
++	const char *page;
++
++	/* Find the FUNCTION_DECL corresponding to the rtx being called. */
++	decl = call_target_decl (x);
++	if (decl == NULL_TREE)
++		return NULL;
++
++	/* See if the function has the new 'banked' attribute.  These
++	 * are numeric instead of text */
++	page = m6809_get_decl_bank (decl);
++	if (page)
++		return page;
++
++	/* No, lookup the type of the function and see if the type
++	 * specifies far or not. */
++	decl_type = TREE_TYPE (decl);
++	if (decl_type == NULL_TREE)
++		return NULL;
++	return far_function_type_p (decl_type);
++}
++
++
++
++/** Outputs the assembly language for a far call. */
++void
++output_far_call_insn (rtx *operands, int has_return)
++{
++	static char page_data[64];
++	const char *called_page;
++
++  /* The logic is the same for functions whether or not there
++	* is a return value.  Skip over the return value in this
++	* case, so that the call location is always operands[0].  */
++  if (has_return)
++	  operands++;
++
++  /* Get the name of the page being called */
++  called_page = far_functionp (operands[0]);
++
++#if 0 /* TODO : broken logic */
++  /* See if the called page name is a 'bank' */
++  if (isdigit (*called_page))
++  {
++    /* New style banking */
++	 if (!strcmp (called_page, current_bank_name))
++	 {
++	 	/* Same page */
++  	  	output_asm_insn ("jsr\t%0", operands);
++	 }
++	 else
++	 {
++	 	/* Different page */
++		output_asm_insn ("jsr\t__far_call_handler\t;new style", operands);
++  	  	output_asm_insn ("\t.dw\t%0", operands);
++		sprintf (page_data, "\t.db\t%s", called_page);
++	 	output_asm_insn (page_data, operands);
++	 }
++	 return;
++  }
++#endif
++
++  /* Are we calling a different page than we are running in? */
++  if (!strcmp (called_page, far_code_page))
++  {
++    /* Same page : no need to execute a far call */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t%C0", operands);
++		else
++			output_asm_insn ("jsr\t%0", operands);
++  }
++  else
++  {
++    /* Different page : need to emit far call thunk */
++
++    /* First output a call to the thunk for making far calls. */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t__far_call_handler", operands);
++		else
++			output_asm_insn ("jsr\t__far_call_handler\t;old style", operands);
++  
++    /* Now output the name of the call site */
++    output_asm_insn ("\t.dw\t%C0", operands);
++  
++    /* Finally output the page number */
++    sprintf (page_data, "\t.db\t%s", far_functionp (operands[0]));
++    output_asm_insn (page_data, operands);
++  }
++}
++
++
++int
++m6809_init_cumulative_args (CUMULATIVE_ARGS cum ATTRIBUTE_UNUSED,
++     tree fntype,
++     rtx libname ATTRIBUTE_UNUSED)
++{
++	cum = 0;
++
++	/* For far functions, the current implementation does not allow for
++	 * stack parameters.  So note whenever the called function is far
++	 * and in a different page than the current one; such a function
++	 * should give an error if a stack parameter is generated. */
++	if (fntype)
++	{
++		const char *called_page = far_function_type_p (fntype);
++		if (called_page && strcmp (called_page, far_code_page) && !TARGET_FAR_STACK_PARAM)
++			cum |= CUM_STACK_INVALID;
++	}
++
++	if (fntype && TYPE_ARG_TYPES (fntype) != 0 &&
++		(TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
++	{
++		/* has variable arguments, cannot use registers */
++		cum |= (CUM_X_MASK | CUM_B_MASK | CUM_STACK_ONLY);
++	}
++
++	if (m6809_abi_version == M6809_ABI_VERSION_STACK)
++	{
++		/* cannot use registers ; only use the stack */
++		cum |= (CUM_STACK_ONLY | CUM_X_MASK | CUM_B_MASK);
++	}
++
++	return cum;
++}
++
++
++rtx
++m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump)
++{
++	if (*cump & CUM_STACK_INVALID)
++	{
++		*cump &= ~CUM_STACK_INVALID;
++		error ("far function needs stack, will not work");
++	}
++	return NULL_RTX;
++}
++
++void m6809_asm_trampoline_template(FILE *f)
++{
++	fprintf(f, "ldy #0000\n");
++	fprintf(f, "jmp 0x0000\n");
++}
++
++/*
++ * Trampoline output:
++ *
++ * ldu #&cxt      4 bytes   --LDY- ?? ??
++ * jmp fnaddr     3 bytes   JMP ?? ??
++ */
++void
++m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
++{
++	rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
++	/* TODO - optimize by generating the entire trampoline code here,
++	 * and removing the template altogether, since there are only two
++	 * bytes there that matter. */
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 5)), fnaddr);
++}
++
++
++/** Echo the version of the compiler and the name of the source file
++ * at the beginning of each assembler output file.  asm_out_file
++ * is a global FILE * pointing to the output stream. */
++void
++m6809_asm_file_start (void)
++{
++	const char *module_name;
++
++	fprintf (asm_out_file, "\n;;; gcc for m6809 : %s %s\n",
++		__DATE__, __TIME__);
++	fprintf (asm_out_file, ";;; %s\n", version_string);
++
++	fprintf (asm_out_file, ";;; ABI version %d\n", m6809_abi_version);
++	fprintf (asm_out_file, ";;; %s\n",
++		(TARGET_BYTE_INT ? "-mint8" : "-mint16"));
++	if (TARGET_EXPERIMENT)
++		fprintf (asm_out_file, ";;; -mexperiment\n");
++	if (TARGET_WPC)
++		fprintf (asm_out_file, ";;; -mwpc\n");
++	if (TARGET_6309)
++		fprintf (asm_out_file, ";;; -m6309\n");
++
++	/* Print the name of the module, which is taken as the base name
++	 * of the input file.
++	 * See the 'User-Defined Symbols' section of the assembler
++	 * documentation for the rules on valid symbols.
++	 */
++	module_name = lbasename (main_input_filename);
++
++	fprintf (asm_out_file, "\t.module\t");
++
++	if (*module_name >= '0' && *module_name <= '9')
++		fprintf (asm_out_file, "_");
++
++	while (*module_name)
++	{
++		if ((*module_name >= '0' && *module_name <= '9')
++			|| (*module_name >= 'A' && *module_name <= 'Z')
++			|| (*module_name >= 'a' && *module_name <= 'z')
++			|| *module_name == '$'
++			|| *module_name == '.'
++			|| *module_name == '_')
++		{
++			fprintf (asm_out_file, "%c", *module_name);
++		}
++		else
++		{
++			fprintf (asm_out_file, "_");
++		}
++		module_name++;
++	}
++
++	fprintf (asm_out_file, "\n");
++}
++
++
++/** Returns true if prologue/epilogue code is required for the
++ * current function being compiled.
++ *
++ * This is just the inverse of whether the function is declared as
++ * 'naked'.
++ */
++int
++prologue_epilogue_required (void)
++{
++	return !m6809_current_function_has_type_attr_p ("naked")
++		&& !m6809_current_function_has_type_attr_p ("noreturn");
++}
++
++
++/** Expand RTL for function entry */
++void
++emit_prologue_insns (void)
++{
++  rtx insn;
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  /* Save all registers used, including the frame pointer */
++  if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++  {
++    insn = emit_insn (
++      gen_rtx_register_pushpop (UNSPEC_PUSH_RS, live_regs));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Allocate space for local variables */
++  if (frame_size != 0)
++  {
++    insn = emit_insn (gen_rtx_stack_adjust (MINUS, frame_size));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Set the frame pointer if it is needed */
++  if (frame_pointer_needed)
++  {
++    insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++}
++
++
++/** Expand RTL for function exit */
++void
++emit_epilogue_insns (bool sibcall_p)
++{
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  if (frame_size != 0)
++    emit_insn (gen_rtx_stack_adjust (PLUS, frame_size));
++
++  if (sibcall_p)
++  {
++    if (live_regs)
++      emit_insn (gen_rtx_register_pushpop (UNSPEC_POP_RS, live_regs));
++  }
++  else
++  {
++    if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++        emit_insn (
++          gen_rtx_register_pushpop (UNSPEC_POP_RS, PC_REGBIT | live_regs));
++  
++    if (m6809_current_function_has_type_attr_p ("interrupt"))
++      emit_jump_insn (gen_return_rti ());
++    else
++      emit_jump_insn (gen_return_rts ());
++  }
++}
++
++#if 0
++/** Predefine some preprocessor names according to the currently
++ * selected compiler options */
++void
++m6809_cpu_cpp_builtins (void)
++{
++	if (TARGET_6309)
++	{
++		builtin_define_std ("__M6309__");
++		builtin_define_std ("__m6309__");
++	}
++	else
++	{
++		builtin_define_std ("__M6809__");
++		builtin_define_std ("__m6809__");
++	}
++
++	if (TARGET_BYTE_INT)
++		builtin_define_std ("__int8__");
++	else
++		builtin_define_std ("__int16__");
++
++	switch (m6809_abi_version)
++	{
++		case M6809_ABI_VERSION_STACK:
++			builtin_define_std ("__regargs__");
++			builtin_define_std ("__ABI_STACK__");
++			break;
++		case M6809_ABI_VERSION_REGS:
++			builtin_define_std ("__ABI_REGS__");
++			break;
++		case M6809_ABI_VERSION_BX:
++			builtin_define_std ("__ABI_BX__");
++			break;
++		default:
++			break;
++	}
++
++	if (TARGET_WPC)
++		builtin_define_std ("__WPC__");
++
++	if (TARGET_DRET)
++		builtin_define_std ("__DRET__");
++}
++#endif
++
++#define MAX_ASM_ASCII_STRING 48
++
++void
++m6809_output_ascii (FILE *fp, const char *str, unsigned long size)
++{
++	unsigned long i;
++	bool use_ascii = true;
++
++	/* If the size is too large, then break this up into multiple
++	outputs.  The assembler can only output roughly 48 bytes at a
++	time.  Note that if there are lots of escape sequences in
++	the string, this may fail. */
++	if (size > MAX_ASM_ASCII_STRING)
++	{
++		m6809_output_ascii (fp, str, MAX_ASM_ASCII_STRING);
++		m6809_output_ascii (fp, str + MAX_ASM_ASCII_STRING, 
++			size - MAX_ASM_ASCII_STRING);
++		return;
++	}
++
++	/* Check for 8-bit codes, which cannot be embedded in an .ascii */
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++		if (c >= 0x80)
++		{
++			use_ascii = false;
++			break;
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\t.ascii \"");
++
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++
++		if (use_ascii)
++		{
++		/* Just output the plain character if it is printable,
++		otherwise output the escape code for the character.
++		The assembler recognizes the same C-style octal escape sequences,
++		except that it only supports 7-bit codes. */
++		if (c >= ' ' && c < 0177 && c != '\\' && c != '"')
++  			putc (c, fp);
++		else switch (c) 
++		{
++			case '\n':
++#ifndef TARGET_COCO
++				fputs ("\\n", fp);
++				break;
++#endif
++				/* On the CoCo, we fallthrough and treat '\n' like '\r'. */
++			case '\r':
++				fputs ("\\r", fp);
++				break;
++			case '\t':
++				fputs ("\\t", fp);
++				break;
++			case '\f':
++				fputs ("\\f", fp);
++				break;
++			case 0:
++				fputs ("\\0", fp);
++				break;
++			default:
++				fprintf (fp, "\\%03o", c);
++				break;
++		}
++		}
++		else
++		{
++			fprintf (fp, "\t.byte\t0x%02X\n", c);
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\"\n");
++}
++
++
++void
++m6809_output_quoted_string (FILE *asm_file, const char *string)
++{
++	char c;
++
++	if (strlen (string) > MAX_ASM_ASCII_STRING)
++	{
++		/* The string length is too large.  We'll have to truncate it.
++		This is only called from debugging functions, so it's usually
++		not critical. */
++
++		char truncated_string[MAX_ASM_ASCII_STRING+1];
++
++		/* Copy as many characters as we can. */
++		strncpy (truncated_string, string, MAX_ASM_ASCII_STRING);
++		truncated_string[MAX_ASM_ASCII_STRING] = '\0';
++		string = truncated_string;
++	}
++
++	/* Copied from toplev.c */
++
++	putc ('\"', asm_file);
++	while ((c = *string++) != 0) {
++		if (ISPRINT (c)) {
++			if (c == '\"' || c == '\\')
++				putc ('\\', asm_file);
++			putc (c, asm_file);
++		}
++      else
++			fprintf (asm_file, "\\%03o", (unsigned char) c);
++	}
++	putc ('\"', asm_file);
++}
++
++
++/** Output the assembly code for a shift instruction where the
++ * shift count is not constant. */
++void
++m6809_output_shift_insn (int rtx_code, rtx *operands)
++{
++	struct shift_opcode *op;
++
++	if (GET_CODE (operands[2]) == CONST_INT)
++		abort ();
++
++	if (optimize_size && GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("jsr\t_ashlhi3", operands);
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("jsr\t_ashrhi3", operands);
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("jsr\t_lshrhi3", operands);
++				break;
++		}
++	}
++	else if (GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", "rola");
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asra", "rorb");
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsra", "rorb");
++				break;
++		}
++	}
++	else
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", NULL);
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asrb", NULL);
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsrb", NULL);
++				break;
++		}
++	}
++}
++
++
++void
++m6809_emit_move_insn (rtx dst, rtx src)
++{
++	emit_insn (gen_rtx_SET (VOIDmode, dst, src));
++	if (ACC_A_REG_P (dst))
++		emit_insn (gen_rtx_USE (VOIDmode, dst));
++}
++
++
++/** Split a complex shift instruction into multiple CPU
++ * shift instructions. */
++void
++m6809_split_shift (enum rtx_code code, rtx *operands)
++{
++	enum machine_mode mode;
++	int count;
++
++	mode = GET_MODE (operands[0]);
++	count = INTVAL (operands[2]);
++	
++	/* Handle a shift count outside the range of 0 .. N-1, where
++	 * N is the mode size in bits.  We normalize the count, and
++	 * for negative counts we also invert the direction of the
++	 * shift. */
++	if ((count < 0) || (count >= 8 * GET_MODE_SIZE (mode)))
++	{
++		if (count < 0)
++		{
++			count = -count;
++			code = (code == ASHIFT) ? ASHIFTRT : ASHIFT;
++		}
++		count %= (8 * GET_MODE_SIZE (mode));
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, count)));
++	}
++
++	/* Handle shift by zero explicitly as a no-op. */
++	if (count == 0)
++	{
++		emit_insn (gen_nop ());
++		return;
++	}
++
++	/* Decompose the shift by a constant N > 8 into two
++	 * shifts, first by 8 and then by N-8.
++	 * This "speeds up" the process for large shifts that would be
++	 * handled below, but allows for some optimization.
++	 * In some cases shift by 8 can be implemented fast.  If an
++	 * instruction to shift by 8 is defined, it will be used here;
++	 * otherwise it will be further decomposed as below. */
++	if (mode == HImode && count > 8)
++	{
++		rtx output = operands[0];
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, 8)));
++
++		/* Unsigned shifts always produce a zero in either the
++		 * upper or lower half of the output; then, that part
++		 * does not need to be shifted anymore.  We modify the
++		 * output and the subsequent instructions to operate in
++		 * QImode only on the relevant part. */
++		if (REG_P (output))
++		{
++			if (code == ASHIFT)
++			{
++				output = gen_rtx_REG (QImode, HARD_A_REGNUM);
++				mode = QImode;
++			}
++			else
++			{
++				output = gen_rtx_REG (QImode, HARD_D_REGNUM);
++				mode = QImode;
++			}
++		}
++
++		m6809_emit_move_insn (output,
++			gen_rtx_fmt_ee (code, mode, copy_rtx (output), 
++				gen_rtx_CONST_INT (VOIDmode, count-8)));
++		return;
++	}
++
++	/* Rewrite the unsigned shift of an 8-bit register by a large constant N
++	 * (near to the maximum of 8) as a rotate and mask. */
++	if (mode == QImode && REG_P (operands[0]) && count >= ((code == ASHIFTRT) ? 7 : 6))
++	{
++		unsigned int mask;
++		unsigned int was_signed = (code == ASHIFTRT);
++
++		code = (code == ASHIFT) ? ROTATERT : ROTATE;
++		if (code == ROTATE)
++			mask = (count == 6) ? 0x03 : 0x01;
++		else
++			mask = (count == 6) ? 0xC0 - 0x100 : 0x80 - 0x100;
++		count = 9 - count;
++
++		do {
++			m6809_emit_move_insn (operands[0],
++				gen_rtx_fmt_ee (code, QImode, operands[1], const1_rtx));
++		} while (--count != 0);
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (AND, QImode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, mask)));
++
++		if (was_signed)
++		{
++			emit_insn (gen_negqi2 (operands[0], copy_rtx (operands[0])));
++			if (ACC_A_REG_P (operands[0]))
++				emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
++		}
++		return;
++	}
++
++	/* Decompose the shift by any constant N > 1 into a sequence
++	 * of N shifts.
++	 * This is done recursively, by creating a shift by 1 and a
++	 * shift by N-1, as long as N>1. */
++	if (count > 1)
++	{
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], const1_rtx));
++	
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], 
++				gen_rtx_CONST_INT (VOIDmode, count-1)));
++		return;
++	}
++	
++	/* Decompose the single shift of a 16-bit quantity into two
++	 * CPU instructions, one for each 8-bit half.
++	 */
++	if (mode == HImode && count == 1)
++	{
++		rtx first, second;
++		enum rtx_code rotate_code;
++
++		rotate_code = (code == ASHIFT) ? ROTATE : ROTATERT;
++
++		/* Split the operand into two 8-bit entities.
++		 * FIRST is the one that will get shifted via a regular CPU
++		 * instruction.
++		 * SECOND is the one that will have the result of the first shift
++		 * rotated in.
++		 *
++		 * We initialize first and second as if we are doing a left shift,
++		 * then swap the operands if it's a right shift.
++		 */
++		if (REG_P (operands[0]))
++		{
++			first = gen_rtx_REG (QImode, HARD_D_REGNUM); /* HARD_B_REGNUM? */
++			second = gen_rtx_REG (QImode, HARD_A_REGNUM);
++		}
++		else
++		{
++			first = adjust_address (operands[0], QImode, 1);
++			second = adjust_address (operands[0], QImode, 0);
++		}
++
++		if (rotate_code == ROTATERT)
++		{
++			rtx tmp; tmp = first; first = second; second = tmp;
++		}
++
++		/* Decompose into a shift and a rotate instruction. */
++		m6809_emit_move_insn (first,
++			gen_rtx_fmt_ee (code, QImode, copy_rtx (first), const1_rtx));
++		m6809_emit_move_insn (second,
++			gen_rtx_fmt_ee (rotate_code, QImode, copy_rtx (second), const1_rtx));
++		return;
++	}
++}
++
++
++/** Adjust register usage based on compile-time flags. */
++void
++m6809_conditional_register_usage (void)
++{
++	unsigned int soft_regno;
++
++#ifdef CONFIG_SOFT_REGS_ALWAYS
++	m6809_soft_regs = CONFIG_SOFT_REGS_ALWAYS;
++#else
++	if (!m6809_soft_reg_count)
++		return;
++	m6809_soft_regs = atoi (m6809_soft_reg_count);
++#endif
++
++	if (m6809_soft_regs == 0)
++		return;
++
++	if (m6809_soft_regs > NUM_M_REGS)
++		m6809_soft_regs = NUM_M_REGS;
++
++	/* Registers are marked FIXED by default.  Free up if
++	the user wishes. */
++	for (soft_regno = 1; soft_regno < m6809_soft_regs; soft_regno++)
++	{
++		fixed_regs[SOFT_M0_REGNUM + soft_regno] = 0;
++
++		/* Mark the softregs as call-clobbered, so that they need
++		 * not be saved/restored on function entry/exit. */
++		call_used_regs[SOFT_M0_REGNUM + soft_regno] = 1;
++	}
++}
++
++
++/** Return a RTX representing how to return a value from a function.
++  VALTYPE gives the type of the value, FUNC identifies the function
++  itself.
++
++  In general, we only care about the width of the result. */
++rtx
++m6809_function_value (const tree valtype, const tree func ATTRIBUTE_UNUSED)
++{
++   unsigned int regno;
++	enum machine_mode mode;
++
++	/* Get the mode (i.e. width) of the result. */
++	mode = TYPE_MODE (valtype);
++
++	if (lookup_attribute ("boolean", TYPE_ATTRIBUTES (valtype)))
++      regno = HARD_Z_REGNUM;
++   else if (mode == QImode || (TARGET_DRET && mode == HImode))
++      regno = HARD_D_REGNUM;
++   else
++      regno = HARD_X_REGNUM;
++   return gen_rtx_REG (mode, regno);
++}
++
++
++/** Return 1 if REGNO is possibly needed to return the result
++of a function, 0 otherwise. */
++int
++m6809_function_value_regno_p (unsigned int regno)
++{
++	if (regno == HARD_Z_REGNUM)
++		return 1;
++	else if ((TARGET_BYTE_INT || TARGET_DRET) && regno == HARD_D_REGNUM)
++		return 1;
++	else if (!TARGET_DRET && regno == HARD_X_REGNUM)
++		return 1;
++	else
++		return 0;
++}
++
++
++#ifdef TRACE_PEEPHOLE
++int
++m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage)
++{
++	if (stage == PEEP_END)
++	{
++		printf ("%s: peephole %d pattern and predicate matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	else if (stage == PEEP_COND)
++	{
++		printf ("%s: peephole %d? at least pattern matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	return 1;
++}
++#else
++int
++m6809_match_peephole2 (unsigned int peephole_id ATTRIBUTE_UNUSED,
++	unsigned int stage ATTRIBUTE_UNUSED)
++{
++	return 1;
++}
++#endif /* TRACE_PEEPHOLE */
++
++
++/** Return 1 if it is OK to store a value of MODE in REGNO. */
++int
++m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
++{
++   /* Soft registers, as they are just memory, can really hold
++   values of any type.  However we restrict them to values of
++   size HImode or QImode to prevent exhausting them for larger
++   values.
++      Word values cannot be placed into the first soft register,
++   as it is the low byte that is being placed there, which
++   corrupts the (non-soft) register before it. */
++   if (M_REGNO_P (regno))
++   {
++      switch (GET_MODE_SIZE (mode))
++      {
++         case 1:
++            return 1;
++         case 2:
++            return regno != SOFT_M0_REGNUM;
++         default:
++            return 0;
++      }
++   }
++
++   /* VOIDmode can be stored anywhere */
++   else if (mode == VOIDmode)
++      return 1;
++
++   /* Zero is a reserved register, but problems occur if we don't
++   say yes here??? */
++   else if (regno == 0)
++      return 1;
++
++   /* For other registers, return true only if the requested size
++   exactly matches the hardware size. */
++   else if ((G_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 2))
++      return 1;
++   else if ((BYTE_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 1))
++      return 1;
++   else
++      return 0;
++}
++
++
++/* exp is the call expression.  DECL is the called function,
++ * or NULL for an indirect call */
++bool
++m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
++{
++	tree type, arg;
++   const char *name;
++	bool result = 0;
++	int argcount = 0;
++	int step = 1;
++
++	/* If there is no DECL, it is an indirect call.
++	 * Never optimize this??? */
++	if (decl == NULL)
++		goto done;
++
++	/* Never allow an interrupt handler to be optimized this way. */
++	if (m6809_function_has_type_attr_p (decl, "interrupt"))
++		goto done;
++
++	/* Skip sibcall if the type can't be found for
++	 * some reason */
++	step++;
++	name = IDENTIFIER_POINTER (DECL_NAME (decl));
++	type = TREE_TYPE (decl);
++	if (type == NULL)
++		goto done;
++
++	/* Skip sibcall if the target is a far function */
++	step++;
++	if (far_function_type_p (type) != NULL)
++		goto done;
++
++	/* Skip sibcall if the called function's arguments are
++	 * variable */
++	step++;
++	if (TYPE_ARG_TYPES (type) == NULL)
++		goto done;
++
++	/* Allow sibcalls in other cases. */
++	result = 1;
++done:
++	/* printf ("%s ok for sibcall? %s, step %d, args %d\n", name, result ? "yes" : "no", step, argcount); */
++	return result;
++}
++
++
++/** Emit code for the 'casesi' pattern.
++ * This pattern is only used in 8-bit mode, and can be disabled
++ * with -mold-case there as well.  The rationale for this is to
++ * do a better job than the simpler but well-tested 'tablejump'
++ * method.
++ *
++ * For small jumptables, where the switch expression is an
++ * 8-bit value, the lookup can be done more efficiently
++ * using the "B,X" style index mode. */
++void
++m6809_do_casesi (rtx index, rtx lower_bound, rtx range,
++	rtx table_label, rtx default_label)
++{
++	enum machine_mode mode;
++	rtx scaled;
++	rtx table_in_reg;
++
++	/* expr.c has to be patched so that it does not promote
++	 * the expression to SImode, but rather to HImode.
++	 * Fail now if that isn't the case. */
++	if (GET_MODE_SIZE (GET_MODE (index)) > GET_MODE_SIZE (HImode))
++		error ("try_casesi promotion bug");
++
++	/* Determine whether or not we are going to work primarily in
++	 * QImode or HImode.  This depends on the size of the index
++	 * into the lookup table.  QImode can only be used when the
++	 * index is less than 0x40, since it will be doubled but
++	 * must remain unsigned. */
++	if ((GET_CODE (range) == CONST_INT) && (INTVAL (range) < 0x40))
++		mode = QImode;
++	else
++		mode = HImode;
++
++	/* Convert to QImode if necessary */
++	if (mode == QImode)
++	{
++		index = gen_lowpart_general (mode, index);
++		lower_bound = gen_lowpart_general (mode, lower_bound);
++	}
++
++	/* Translate from case value to table index by subtraction */
++	if (lower_bound != const0_rtx)
++		index = expand_binop (mode, sub_optab, index, lower_bound,
++			NULL_RTX, 0, OPTAB_LIB_WIDEN);
++
++	/* Emit compare-and-jump to test for index out-of-range */
++	emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
++		default_label);
++
++	/* Put the table address is in a register */
++	table_in_reg = gen_reg_rtx (Pmode);
++	emit_move_insn (table_in_reg, gen_rtx_LABEL_REF (Pmode, table_label));
++
++	/* Emit table lookup and jump */
++	if (mode == QImode)
++	{
++		/* Scale the index */
++		scaled = gen_reg_rtx (QImode);
++		emit_insn (gen_ashlqi3 (scaled, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_short_offset (scaled, table_in_reg));
++	}
++	else
++	{
++		/* Scale the index */
++		emit_insn (gen_ashlhi3 (index, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_long_offset (index, table_in_reg));
++	}
++
++	/* Copied from expr.c */
++	if (!CASE_VECTOR_PC_RELATIVE && !flag_pic)
++		emit_barrier ();
++}
++
++
++/** Output the assembly code for a 32-bit add/subtract. */
++void
++m6809_output_addsi3 (int rtx_code, rtx *operands)
++{
++	rtx xoperands[8];
++	rtx dst = operands[0];
++
++	/* Prepare the operands by splitting each SImode into two HImodes
++	that can be operated independently.  The high word of operand 1
++	is further divided into two QImode components for use with 'adc'
++	style instructions. */
++	xoperands[7] = operands[3];
++
++	xoperands[0] = adjust_address (dst, HImode, 2);
++	xoperands[3] = adjust_address (dst, HImode, 0);
++
++#if 1
++	xoperands[2] = adjust_address (operands[1], HImode, 2);
++	xoperands[6] = adjust_address (operands[1], HImode, 0);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[1] = gen_int_mode (INTVAL (operands[2]) & 0xFFFF, HImode);
++		xoperands[4] = gen_int_mode ((INTVAL (operands[2]) >> 24) & 0xFF, QImode);
++		xoperands[5] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFF, QImode);
++	}
++	else
++	{
++		xoperands[1] = adjust_address (operands[2], HImode, 2);
++		xoperands[4] = adjust_address (operands[2], QImode, 0);
++		xoperands[5] = adjust_address (operands[2], QImode, 1);
++	}
++
++#endif
++
++#if 0
++	xoperands[1] = adjust_address (operands[1], HImode, 2);
++	xoperands[4] = adjust_address (operands[1], QImode, 0);
++	xoperands[5] = adjust_address (operands[1], QImode, 1);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[2] = gen_int_mode ((INTVAL (operands[2])) & 0xFFFF, HImode);
++		xoperands[6] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFFFF, HImode);
++	}
++	else
++	{
++		xoperands[2] = adjust_address (operands[2], HImode, 2);
++		xoperands[6] = adjust_address (operands[2], HImode, 0);
++	}
++#endif
++
++	/* Output the assembly code. */
++	if (rtx_code == PLUS)
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("add%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("adcb\t%5", xoperands);
++		output_asm_insn ("adca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++	else
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("sub%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("sbcb\t%5", xoperands);
++		output_asm_insn ("sbca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++}
++
++
++#if 0
++/** Output the assembly code for a 32-bit shift.
++Operands 0 and 1 must be the same rtx, forced by a matching
++constraint.  Operand 2 must be a CONST_INT.  Operand 3 is
++"d" in case a temporary reg is needed. */
++void
++m6809_output_shiftsi3 (int rtx_code, rtx *operands)
++{
++	unsigned int count = INTVAL (operands[2]) % 32;
++	unsigned int size = 4; /* sizeof (SImode) */
++	int s;
++	rtx xoperands[4];
++	int op;
++	int start, end, step;
++
++	/* Initialize */
++	if (rtx_code == ASHIFT)
++	{
++		start = size-1;
++		end = -1;
++		step = -1;
++	}
++	else
++	{
++		start = 0;
++		end = size;
++		step = 1;
++	}
++
++	xoperands[2] = operands[2];
++	xoperands[3] = operands[3];
++
++	if (count <= 0)
++		abort ();
++	if (rtx_code == ROTATE || rtx_code == ROTATERT)
++		abort ();
++
++	/* Extract bit shifts over 16 bits by HImode moves. */
++	if (count >= 16)
++	{
++	}
++
++	/* Extract bit shifts over 8 bits by QImode moves. */
++	if (count >= 8)
++	{
++	}
++
++	/* Iterate over the number of bits to be shifted. */
++	while (count > 0)
++	{
++		/* Each bit to be shifted requires 1 proper bit shift
++		and 3 rotates. */
++
++		/* First, do the arithmetic/logical shift.  Left shifts
++		start from the LSB; right shifts start from the MSB. */
++		xoperands[0] = adjust_address (operands[0], QImode, start);
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("asl\t%0", xoperands);
++				start--;
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("asr\t%0", xoperands);
++				start++;
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("lsr\t%0", xoperands);
++				start++;
++				break;
++		}
++
++		/* Next, rotate the other bytes */
++		for (s = start; s != end; s += step)
++		{
++			xoperands[0] = adjust_address (operands[0], QImode, s);
++			switch (rtx_code)
++			{
++				case ASHIFT:
++					output_asm_insn ("rol\t%0", xoperands);
++					break;
++				case ASHIFTRT:
++				case LSHIFTRT:
++					output_asm_insn ("ror\t%0", xoperands);
++					break;
++			}
++		}
++		count--;
++	}
++}
++#endif
++
++int
++power_of_two_p (unsigned int n)
++{
++	return (n & (n-1)) == 0;
++}
++
++
++int
++m6809_can_eliminate (int from, int to)
++{
++	if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
++		return !frame_pointer_needed;
++	return 1;
++}
++
++
++int
++m6809_initial_elimination_offset (int from, int to)
++{
++	switch (from)
++	{
++		case ARG_POINTER_REGNUM:
++			return get_frame_size () + m6809_get_regs_size (m6809_get_live_regs ());
++		case FRAME_POINTER_REGNUM:
++			return get_frame_size ();
++		default:
++			gcc_unreachable ();
++	}
++}
++
++
++bool
++m6809_frame_pointer_required (void)
++{
++	return false;
++}
++
++
++/* Defines the target-specific hooks structure. */
++struct gcc_target targetm = TARGET_INITIALIZER;
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.h gcc-4.6.4/gcc/config/m6809/m6809.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.h	2015-07-20 21:56:53.518727644 -0600
+@@ -0,0 +1,1352 @@
++/* Definitions of target machine for GNU compiler.  MC6809 version.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to egcs-1.1.2 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ changes for gcc-3.1.1 by ???
++
++ further changes for gcc-3.1.1 and beyond by Brian Dominy
++ (brian@oddchange.com)
++
++ even more changes for gcc-4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++
++/* Helper macros for creating strings with macros */
++#define C_STRING(x) C_STR(x)
++#define C_STR(x) #x
++
++/* Certain parts of GCC include host-side includes, which is bad.
++ * Some things that get pulled in need to be undone.
++ */
++#undef HAVE_GAS_HIDDEN
++
++/* Names to predefine in the preprocessor for this target machine.  */
++/*#define TARGET_CPU_CPP_BUILTINS() m6809_cpu_cpp_builtins () */
++#define TARGET_CPU_CPP_BUILTINS() do \
++	{ \
++		if (TARGET_6309) \
++		{ \
++			builtin_define_std ("__M6309__"); \
++			builtin_define_std ("__m6309__"); \
++		} \
++		else \
++		{ \
++			builtin_define_std ("__M6809__"); \
++			builtin_define_std ("__m6809__"); \
++		} \
++ \
++		if (TARGET_BYTE_INT) \
++			builtin_define_std ("__int8__"); \
++		else \
++			builtin_define_std ("__int16__"); \
++ \
++		switch (m6809_abi_version) \
++		{ \
++			case M6809_ABI_VERSION_STACK: \
++				builtin_define_std ("__regargs__"); \
++				builtin_define_std ("__ABI_STACK__"); \
++				break; \
++			case M6809_ABI_VERSION_REGS: \
++				builtin_define_std ("__ABI_REGS__"); \
++				break; \
++			case M6809_ABI_VERSION_BX: \
++				builtin_define_std ("__ABI_BX__"); \
++				break; \
++			default: \
++				break; \
++		} \
++ \
++		if (TARGET_WPC) \
++			builtin_define_std ("__WPC__"); \
++ \
++		if (TARGET_DRET) \
++			builtin_define_std ("__DRET__"); \
++	} while (0)
++
++/* As an embedded target, we have no libc.  */
++#ifndef inhibit_libc
++#define inhibit_libc
++#endif
++
++/* Print subsidiary information on the compiler version in use.  */
++#define TARGET_VERSION fprintf (stderr, " (MC6809)");
++
++/* Run-time compilation parameters selecting different hardware subsets.  */
++/*extern int target_flags; */
++extern short *reg_renumber;	/* def in local_alloc.c */
++
++/* Runtime current values of section names */
++extern int section_changed;
++extern char code_section_op[], data_section_op[], bss_section_op[];
++
++#define WARNING_OPT 0,
++/*extern const char *m6809_abi_version_ptr; */
++extern unsigned int m6809_soft_regs;
++extern unsigned int m6809_abi_version;
++
++/* ABI versions */
++
++#define M6809_ABI_VERSION_STACK 0
++#define M6809_ABI_VERSION_REGS 1
++#define M6809_ABI_VERSION_BX 2
++#define M6809_ABI_VERSION_LATEST  (M6809_ABI_VERSION_BX)
++
++/* Allow $ in identifiers */
++#define DOLLARS_IN_IDENTIFIERS 1
++
++/*--------------------------------------------------------------
++	Target machine storage layout
++--------------------------------------------------------------*/
++
++/* Define this if most significant bit is lowest numbered
++   in instructions that operate on numbered bit-fields.  */
++#define BITS_BIG_ENDIAN 0
++
++/* Define to 1 if most significant byte of a word is the lowest numbered. */
++#define BYTES_BIG_ENDIAN 1
++
++/* Define to 1 if most significant word of a multiword value is the lowest numbered. */
++#define WORDS_BIG_ENDIAN 1
++
++/* Number of bits in an addressible storage unit */
++#define BITS_PER_UNIT 8
++
++/* Width in bits of a "word", or the contents of a machine register.
++ * Although the 6809 has a few byte registers, define this to 16-bits
++ * since this is the natural size of most registers. */
++#define BITS_PER_WORD 16
++
++/* Width of a word, in units (bytes).  */
++#define UNITS_PER_WORD (BITS_PER_WORD/8)
++
++/* Width in bits of a pointer.  See also the macro `Pmode' defined below.  */
++#define POINTER_SIZE 16
++
++/* Allocation boundary (bits) for storing pointers in memory.  */
++#define POINTER_BOUNDARY 8
++
++/* Allocation boundary (bits) for storing arguments in argument list.  */
++/* PARM_BOUNDARY is divided by BITS_PER_WORD in expr.c -- tej */
++#define PARM_BOUNDARY 8
++
++/* Boundary (bits) on which stack pointer should be aligned.  */
++#define STACK_BOUNDARY 8
++
++/* Allocation boundary (bits) for the code of a function.  */
++#define FUNCTION_BOUNDARY 8
++
++/* Alignment of field after `int : 0' in a structure.  */
++#define EMPTY_FIELD_BOUNDARY 8
++
++/* Every structure's size must be a multiple of this.  */
++#define STRUCTURE_SIZE_BOUNDARY 8
++
++/* Largest mode size to use when putting an object, including
++ * a structure, into a register.  By limiting this to 16, no
++ * 32-bit objects will ever be allocated to a pair of hard
++ * registers.  This is a good thing, since there aren't that
++ * many of them.  32-bit objects are only needed for floats
++ * and "long long"s.  Larger values have been tried and did not
++ * work. */
++#define MAX_FIXED_MODE_SIZE 16
++
++/* No data type wants to be aligned rounder than this.  */
++#define BIGGEST_ALIGNMENT 8
++
++/* Define this if move instructions will actually fail to work
++   when given unaligned data.  */
++#define STRICT_ALIGNMENT 0
++
++/*--------------------------------------------------------------
++	 Standard register usage.
++--------------------------------------------------------------*/
++
++/* Register values as bitmasks.
++ * TODO : merge D_REGBIT and B_REGBIT, and treat this as the same
++ * register. */
++#define RSVD1_REGBIT    (1 << HARD_RSVD1_REGNUM)
++#define D_REGBIT			(1 << HARD_D_REGNUM)
++#define X_REGBIT			(1 << HARD_X_REGNUM)
++#define Y_REGBIT			(1 << HARD_Y_REGNUM)
++#define U_REGBIT			(1 << HARD_U_REGNUM)
++#define S_REGBIT			(1 << HARD_S_REGNUM)
++#define PC_REGBIT			(1 << HARD_PC_REGNUM)
++#define Z_REGBIT        (1 << HARD_Z_REGNUM)
++#define A_REGBIT			(1 << HARD_A_REGNUM)
++#define B_REGBIT			(1 << HARD_B_REGNUM)
++#define CC_REGBIT			(1 << HARD_CC_REGNUM)
++#define DP_REGBIT			(1 << HARD_DP_REGNUM)
++#define SOFT_FP_REGBIT  (1 << SOFT_FP_REGNUM)
++#define SOFT_AP_REGBIT  (1 << SOFT_AP_REGNUM)
++#define M_REGBIT(n)		(1 << (SOFT_M0_REGNUM + n))
++
++/* Macros for dealing with set of registers.
++ * A register set is just a bitwise-OR of all the register
++ * bitmask values. */
++
++/* Which registers can hold 8-bits */
++#define BYTE_REGSET \
++	(Z_REGBIT | A_REGBIT | D_REGBIT | CC_REGBIT | DP_REGBIT)
++
++/* Which registers can hold 16-bits.
++ * Note: D_REGBIT is defined as both an 8-bit and 16-bit register */
++#define WORD_REGSET \
++	(D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT | SOFT_FP_REGBIT | SOFT_AP_REGBIT | RSVD1_REGBIT)
++
++/* Returns nonzero if a given REGNO is in the REGSET. */
++#define REGSET_CONTAINS_P(regno, regset)  (((1 << (regno)) & (regset)) != 0)
++
++/* Defines related to the number of soft registers supported.
++ * The actual number used may be less depending on -msoft-reg-count.
++ * If you change one of these, you should change them all. */
++#define NUM_M_REGS 8
++#define M_REGS_FIXED 1, 1, 1, 1, 1, 1, 1, 1
++#define M_REGS_CALL_USED 1, 1, 1, 1, 1, 1, 1, 1
++#define HARD_M_REGNUMS \
++   SOFT_M0_REGNUM+0, SOFT_M0_REGNUM+1, SOFT_M0_REGNUM+2, SOFT_M0_REGNUM+3, \
++   SOFT_M0_REGNUM+4, SOFT_M0_REGNUM+5, SOFT_M0_REGNUM+6, SOFT_M0_REGNUM+7
++
++#define SOFT_M_REGBITS  (((1UL << NUM_M_REGS) - 1) << (SOFT_M0_REGNUM))
++
++/* Number of actual hardware registers.
++   The hardware registers are assigned numbers for the compiler
++   from 0 to just below FIRST_PSEUDO_REGISTER.
++   All registers that the compiler knows about must be given numbers,
++   even those that are not normally considered general registers.
++   Make sure the constant below matches the value of SOFT_M0_REGNUM;
++   for some reason, GCC won't compile if that name is used here directly. */
++#ifdef SOFT_M0_REGNUM
++#if (SOFT_M0_REGNUM != 14)
++#error "bad register numbering"
++#endif
++#endif
++#define FIRST_PSEUDO_REGISTER (14 + NUM_M_REGS)
++
++/* 1 for registers that have pervasive standard uses
++   and are not available for the register allocator.
++   The psuedoregisters (M_REGS) are declared fixed here, but
++   will be unfixed if -msoft-reg-count is seen later.  */
++#define FIXED_REGISTERS \
++    {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, M_REGS_FIXED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* 1 for registers not available across function calls.
++   These must include the FIXED_REGISTERS and also any
++   registers that can be used without being saved.
++   The latter must include the registers where values are returned
++   and the register where structure-value addresses are passed.
++   Aside from that, you can include as many other registers as you like.  */
++#define CALL_USED_REGISTERS \
++    {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, M_REGS_CALL_USED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* Return number of consecutive hard regs needed starting at reg REGNO
++   to hold something of mode MODE.
++	For the 6809, we distinguish between word-length and byte-length
++	registers. */
++#define HARD_REGNO_NREGS(REGNO, MODE) \
++   (REGSET_CONTAINS_P (REGNO, WORD_REGSET) ? \
++		((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : \
++      (GET_MODE_SIZE (MODE)))
++
++
++/* Value is 1 if hard register REGNO can hold a value
++of machine-mode MODE. */
++#define HARD_REGNO_MODE_OK(REGNO, MODE) m6809_hard_regno_mode_ok (REGNO, MODE)
++
++/* Value is 1 if it is a good idea to tie two pseudo registers
++   when one has mode MODE1 and one has mode MODE2.
++   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
++   for any hard reg, then this must be 0 for correct output.  */
++#define MODES_TIEABLE_P(MODE1, MODE2) 0
++
++/* Specify the registers used for certain standard purposes.
++   The values of these macros are register numbers.  */
++
++/* program counter if referenced as a register */
++#define PC_REGNUM HARD_PC_REGNUM
++
++/* Register to use for pushing function arguments.  */
++#define STACK_POINTER_REGNUM HARD_S_REGNUM
++
++/* Base register for access to local variables of the function.
++ * Before reload, FRAME_POINTER_REGNUM will be used.  Later,
++ * the elimination pass will convert these to STACK_POINTER_REGNUM
++ * if possible, or else HARD_FRAME_POINTER_REGNUM.  The idea is to
++ * avoid tying up a hard register (U) for the frame pointer if
++ * it can be eliminated entirely, making it available for use as
++ * a general register. */
++#define FRAME_POINTER_REGNUM       SOFT_FP_REGNUM
++#define HARD_FRAME_POINTER_REGNUM  HARD_U_REGNUM
++
++/* Define a table of possible eliminations.
++ * The idea is to try to avoid using hard registers for the argument
++ * and frame pointers if they can be derived from the stack pointer
++ * instead, which already has a hard register reserved for it.
++ *
++ * The order of entries in this table will try to convert
++ * ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM into stack pointer
++ * references first, but if that fails, they will be converted to use
++ * HARD_FRAME_POINTER_REGNUM.
++ */
++#define ELIMINABLE_REGS \
++{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
++
++/* #define CAN_ELIMINATE(FROM, TO) m6809_can_eliminate (FROM, TO) */
++
++/* Define how to offset the frame or argument pointer to turn it
++ * into a stack pointer reference.  This is based on the way that
++ * the frame is constructed in the function prologue. */
++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
++	(OFFSET) = m6809_initial_elimination_offset (FROM, TO)
++
++/* Base register for access to arguments of the function.
++ * This is only used prior to reload; no instructions will ever
++ * be output referring to this register. */
++#define ARG_POINTER_REGNUM SOFT_AP_REGNUM
++
++/* Register in which static-chain is passed to a function.  */
++#define STATIC_CHAIN_REGNUM HARD_Y_REGNUM
++
++/* #define CONDITIONAL_REGISTER_USAGE (m6809_conditional_register_usage ()) */
++
++/* Order in which hard registers are allocated to pseudos.
++ *
++ * Since the D register is the only valid reg for 8-bit values
++ * now, avoid using it for 16-bit values by putting it after all
++ * other 16-bits.
++ *
++ * Prefer X first since the first 16-bit function argument goes
++ * there.  We may be able to pass in to a subroutine without
++ * a copy.
++ *
++ * Prefer U over Y since instructions using Y take one extra
++ * byte, and thus one extra cycle to execute.
++ */
++#define REG_ALLOC_ORDER \
++   {  HARD_X_REGNUM, HARD_U_REGNUM, HARD_Y_REGNUM, HARD_D_REGNUM, \
++	   HARD_M_REGNUMS, HARD_S_REGNUM, HARD_PC_REGNUM, \
++		HARD_B_REGNUM, HARD_A_REGNUM, HARD_CC_REGNUM, \
++		HARD_DP_REGNUM, SOFT_FP_REGNUM, SOFT_AP_REGNUM, \
++		6, HARD_Z_REGNUM }
++
++/*--------------------------------------------------------------
++	classes of registers
++--------------------------------------------------------------*/
++
++/* Define the classes of registers for register constraints in the
++   machine description.  Also define ranges of constants.
++
++   One of the classes must always be named ALL_REGS and include all hard regs.
++   If there is more than one class, another class must be named NO_REGS
++   and contain no registers.
++
++   The name GENERAL_REGS must be the name of a class (or an alias for
++   another name such as ALL_REGS).  This is the class of registers
++   that is allowed by "g" or "r" in a register constraint.
++   Also, registers outside this class are allocated only when
++   instructions express preferences for them.
++
++   The classes must be numbered in nondecreasing order; that is,
++   a larger-numbered class must never be contained completely
++   in a smaller-numbered class.
++
++   For any two classes, it is very desirable that there be another
++   class that represents their union.  */
++   
++enum reg_class {
++    NO_REGS,    /* The trivial class with no registers in it */
++    D_REGS,     /* 16-bit (word (HI)) data (D) */
++    ACC_A_REGS, /* The A register */
++    ACC_B_REGS, /* The B register */
++	 X_REGS,     /* The X register */
++	 Z_REGS,     /* The Z (zero-bit) register */
++    Q_REGS,     /* 8-bit (byte (QI)) data (A,B) */
++    M_REGS,     /* 8-bit (byte (QI)) soft registers */
++	 CC_REGS,    /* 8-bit condition code register */
++    I_REGS,     /* An index register (A,B,D) */
++    T_REGS,     /* 16-bit addresses, not including stack or PC (X,Y,U) */
++    A_REGS,     /* 16-bit addresses (X,Y,U,S,PC) */
++	 S_REGS,     /* 16-bit soft registers (FP, AP) */
++	 P_REGS,     /* 16-bit pushable registers (D,X,Y,U); omit PC and S */
++    G_REGS,     /* 16-bit data and address (D,X,Y,U,S,PC) */
++    ALL_REGS,   /* All registers */
++    LIM_REG_CLASSES
++};
++
++#define N_REG_CLASSES (int) LIM_REG_CLASSES
++
++/* Since GENERAL_REGS is a smaller class than ALL_REGS,
++   it is not an alias to ALL_REGS, but to G_REGS. */
++#define GENERAL_REGS G_REGS
++
++/* Give names of register classes as strings for dump file.   */
++#define REG_CLASS_NAMES \
++ {  "NO_REGS", "D_REGS", "ACC_A_REGS", "ACC_B_REGS", "X_REGS", "Z_REGS", "Q_REGS", "M_REGS", \
++	 "CC_REGS", "I_REGS", "T_REGS", "A_REGS", "S_REGS", "P_REGS", "G_REGS", \
++	 "ALL_REGS" }
++
++/* Define which registers fit in which classes.
++   This is an initializer for a vector of HARD_REG_SET
++   of length N_REG_CLASSES.  */
++
++#define D_REGSET	(D_REGBIT)
++#define ACC_A_REGSET (A_REGBIT)
++#define ACC_B_REGSET (D_REGBIT)
++#define X_REGSET (X_REGBIT)
++#define Z_REGSET (Z_REGBIT)
++#define Q_REGSET (D_REGBIT | A_REGBIT)
++#define M_REGSET (SOFT_M_REGBITS)
++#define CC_REGSET (CC_REGBIT)
++#define I_REGSET (A_REGBIT | B_REGBIT | D_REGBIT)
++#define T_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT)
++#define A_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT)
++#define S_REGSET (SOFT_FP_REGBIT | SOFT_AP_REGBIT)
++#define P_REGSET (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT)
++#define G_REGSET \
++   (D_REGSET | Q_REGSET | I_REGSET | A_REGSET | M_REGSET | S_REGSET)
++#define ALL_REGSET (G_REGSET)
++
++#define REG_CLASS_CONTENTS { \
++	{0}, \
++	{D_REGSET}, \
++   {ACC_A_REGSET}, \
++   {ACC_B_REGSET}, \
++   {X_REGSET}, \
++   {Z_REGSET}, \
++	{Q_REGSET}, \
++	{M_REGSET}, \
++   {CC_REGSET}, \
++	{I_REGSET}, \
++	{T_REGSET}, \
++	{A_REGSET}, \
++	{S_REGSET}, \
++	{P_REGSET}, \
++	{G_REGSET}, \
++	{ALL_REGSET}, \
++}
++
++/* The same information, inverted.
++ * This is defined to use the REG_CLASS_CONTENTS defines above, so that
++ * these two sets of definitions are always consistent. */
++
++#define REGNO_REG_CLASS(REGNO) \
++  (D_REGNO_P (REGNO) ? D_REGS : \
++  (Z_REGNO_P (REGNO) ? Z_REGS : \
++  (ACC_A_REGNO_P (REGNO) ? ACC_A_REGS : \
++  (ACC_B_REGNO_P (REGNO) ? ACC_B_REGS : \
++  (X_REGNO_P (REGNO) ? X_REGS : \
++  (Q_REGNO_P (REGNO) ? Q_REGS : \
++  (M_REGNO_P (REGNO) ? M_REGS : \
++  (CC_REGNO_P (REGNO) ? CC_REGS : \
++  (I_REGNO_P (REGNO) ? I_REGS : \
++  (T_REGNO_P (REGNO) ? T_REGS : \
++  (A_REGNO_P (REGNO) ? A_REGS : \
++  (S_REGNO_P (REGNO) ? S_REGS : \
++  (P_REGNO_P (REGNO) ? P_REGS : \
++  (G_REGNO_P (REGNO) ? G_REGS : ALL_REGS))))))))))))))
++
++#define D_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, D_REGSET))
++#define ACC_A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_A_REGSET))
++#define ACC_B_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_B_REGSET))
++#define X_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, X_REGSET))
++#define Z_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Z_REGSET))
++#define Q_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Q_REGSET))
++#define M_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, M_REGSET))
++#define CC_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, CC_REGSET))
++#define I_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, I_REGSET))
++#define T_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, T_REGSET))
++#define A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, A_REGSET))
++#define S_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, S_REGSET))
++#define P_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, P_REGSET))
++#define G_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, G_REGSET))
++
++/* Macros that test an rtx 'X' to see if it's in a particular
++ * register class.  'X' need not be a REG necessarily. */
++
++#define D_REG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
++#define ACC_A_REG_P(X) (REG_P (X) && ACC_A_REGNO_P (REGNO (X)))
++#define ACC_B_REG_P(X) (REG_P (X) && ACC_B_REGNO_P (REGNO (X)))
++#define X_REG_P(X) (REG_P (X) && X_REGNO_P (REGNO (X)))
++#define Z_REG_P(X) (REG_P (X) && Z_REGNO_P (REGNO (X)))
++#define I_REG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
++#define T_REG_P(X) (REG_P (X) && T_REGNO_P (REGNO (X)))
++#define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
++#define S_REG_P(X) (REG_P (X) && S_REGNO_P (REGNO (X)))
++#define P_REG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
++#define Q_REG_P(X) (REG_P (X) && Q_REGNO_P (REGNO (X)))
++#define M_REG_P(X) (REG_P (X) && M_REGNO_P (REGNO (X)))
++#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
++
++/* Redefine this in terms of BYTE_REGSET */
++#define BYTE_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, BYTE_REGSET))
++
++/* The class value for index registers, and the one for base regs.  */
++#define INDEX_REG_CLASS I_REGS
++#define BASE_REG_CLASS A_REGS
++
++/* Get reg_class from a letter in the machine description.  */
++#define REG_CLASS_FROM_LETTER(C) \
++  (((C) == 'a' ? A_REGS : \
++   ((C) == 'd' ? D_REGS : \
++	((C) == 'x' ? I_REGS : \
++	((C) == 't' ? M_REGS : \
++	((C) == 'c' ? CC_REGS : \
++	((C) == 'A' ? ACC_A_REGS : \
++	((C) == 'B' ? ACC_B_REGS : \
++	((C) == 'v' ? X_REGS : \
++	((C) == 'u' ? S_REGS : \
++	((C) == 'U' ? P_REGS : \
++	((C) == 'T' ? T_REGS : \
++	((C) == 'z' ? Z_REGS : \
++   ((C) == 'q' ? Q_REGS : NO_REGS))))))))))))))
++
++/*--------------------------------------------------------------
++   The letters I through O in a register constraint string
++   can be used to stand for particular ranges of immediate operands.
++   This macro defines what the ranges are.
++   C is the letter, and VALUE is a constant value.
++   Return 1 if VALUE is in the range specified by C.
++
++   For the 6809, J, K, L are used for indexed addressing.
++   `I' is used for the constant 1.
++   `J' is used for the 5-bit offsets.
++   `K' is used for the 8-bit offsets.
++   `L' is used for the range of signed numbers that fit in 16 bits.
++   `M' is used for the exact value '8'.
++   `N' is used for the constant -1.
++   `O' is used for the constant 0.
++--------------------------------------------------------------*/
++
++#define CONST_OK_FOR_LETTER_P(VALUE, C) \
++  ((C) == 'I' ? ((VALUE) == 1) : \
++   (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
++   (C) == 'K' ? ((VALUE) >= -128 && (VALUE) <= 127) : \
++   (C) == 'L' ? ((VALUE) >= -32768 && (VALUE) <= 32767) : \
++   (C) == 'M' ? ((VALUE) == 8) : \
++   (C) == 'N' ? ((VALUE) == -1) : \
++   (C) == 'O' ? ((VALUE) == 0) : 0)
++
++/* Similar, but for floating constants, and defining letters G and H.
++   No floating-point constants are valid on MC6809.  */
++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
++   ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
++     && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
++
++/* Given an rtx X being reloaded into a reg required to be
++   in class CLASS, return the class of reg to actually use.
++   In general this is just CLASS; but on some machines
++   in some cases it is preferable to use a more restrictive class.  */
++#define PREFERRED_RELOAD_CLASS(X,CLASS) m6809_preferred_reload_class(X,CLASS)
++
++#define SMALL_REGISTER_CLASSES  1
++
++/* Return the maximum number of consecutive registers
++   needed to represent mode MODE in a register of class CLASS.  */
++#define CLASS_MAX_NREGS(CLASS, MODE) \
++    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++
++/*--------------------------------------------------------------
++	Stack layout; function entry, exit and calling.
++--------------------------------------------------------------*/
++
++/* Define this if pushing a word on the stack
++   makes the stack pointer a smaller address.  */
++#define STACK_GROWS_DOWNWARD
++
++
++/* Define this if the nominal address of the stack frame
++   is at the high-address end of the local variables;
++   that is, each additional local variable allocated
++   goes at a more negative offset in the frame.  */
++#define FRAME_GROWS_DOWNWARD 1
++
++
++/* Offset within stack frame to start allocating local variables at.
++   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
++   first local allocated.  Otherwise, it is the offset to the BEGINNING
++   of the first local allocated.  */
++#define STARTING_FRAME_OFFSET 0
++
++
++/* Always push stack arguments for now.  Accumulation is not yet working. */
++#define PUSH_ROUNDING(BYTES) (BYTES)
++
++
++/* Offset of first parameter from the argument pointer register value.
++ * ARG_POINTER_REGNUM is defined to point to the return address pushed
++ * onto the stack, so we must offset by 2 bytes to get to the arguments. */
++#define FIRST_PARM_OFFSET(FNDECL) 2
++
++/* Value is 1 if returning from a function call automatically
++   pops the arguments described by the number-of-args field in the call.
++   FUNTYPE is the data type of the function (as a tree),
++   or for a library call it is an identifier node for the subroutine name. */
++/* #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 */
++
++/* Define how to find the value returned by a function.
++   VALTYPE is the data type of the value (as a tree).
++   If the precise function being called is known, FUNC is its FUNCTION_DECL;
++   otherwise, FUNC is 0.  */
++#define FUNCTION_VALUE(VALTYPE, FUNC) m6809_function_value (VALTYPE, FUNC)
++
++/* Define how to find the value returned by a library function
++   assuming the value has mode MODE.  */
++
++/* All return values are in the X-register. */
++#define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, HARD_X_REGNUM)
++
++/* Define this if using the nonreentrant convention for returning
++   structure and union values.  No; it is inefficient and buggy. */
++#undef PCC_STATIC_STRUCT_RETURN
++
++/* 1 if N is a possible register number for a function value. */
++#define FUNCTION_VALUE_REGNO_P(N) m6809_function_value_regno_p (N)
++
++/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
++   more than one register.  */
++#define NEEDS_UNTYPED_CALL 1
++
++/* 1 if N is a possible register number for function argument passing. */
++#define FUNCTION_ARG_REGNO_P(N) \
++	((m6809_abi_version != M6809_ABI_VERSION_STACK) ? \
++   	(((N) == HARD_D_REGNUM) || ((N) == HARD_X_REGNUM)) : \
++		0)
++
++/*--------------------------------------------------------------
++	Argument Lists
++--------------------------------------------------------------*/
++
++/* Cumulative arguments are tracked in a single integer, 
++ * which is the number of bytes of arguments scanned so far,
++ * plus which registers have already been used.  The register
++ * info is kept in some of the upper bits */
++#define CUMULATIVE_ARGS unsigned int
++
++#define CUM_STACK_ONLY 0x80000000
++#define CUM_X_MASK     0x40000000
++#define CUM_B_MASK     0x20000000
++#define CUM_STACK_INVALID 0x10000000
++#define CUM_STACK_MASK 0xFFFFFFF
++
++#define CUM_ADVANCE_8BIT(cum) \
++	(((cum) & CUM_B_MASK) ? (cum)++ : ((cum) |= CUM_B_MASK))
++
++#define CUM_ADVANCE_16BIT(cum) \
++	(((cum) & CUM_X_MASK) ? (cum) += 2 : ((cum) |= CUM_X_MASK))
++
++/* 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.
++	N_NAMED was added in gcc 3.4 and is not used currently. */
++#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED) \
++	((CUM) = m6809_init_cumulative_args (CUM, FNTYPE, LIBNAME))
++
++#define FUNCTION_ARG_SIZE(MODE, TYPE)	\
++  ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)	\
++   : (unsigned) int_size_in_bytes (TYPE))
++
++/* 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.)  */
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
++	 (((MODE == QImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_8BIT (CUM) : \
++	  ((MODE == HImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_16BIT (CUM) : \
++	  ((CUM) = ((CUM) + (TYPE ? int_size_in_bytes (TYPE) : 2))))
++
++/* Define where to put the arguments to a function.
++   Value is zero to push the argument on the stack,
++   or a hard register rtx in which to store the argument.
++	This macro is used _before_ FUNCTION_ARG_ADVANCE.
++
++	For the 6809, the first 8-bit function argument can be placed into B,
++	and the first 16-bit arg can go into X.  All other arguments
++	will be pushed onto the stack.
++
++	Command-line options can adjust this behavior somewhat.
++ */
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++	((MODE == VOIDmode) ? NULL_RTX : \
++	((MODE == BLKmode) || (GET_MODE_SIZE (MODE) > 2)) ? NULL_RTX : \
++	((MODE == QImode) && !((CUM) & (CUM_STACK_ONLY | CUM_B_MASK))) ? \
++		gen_rtx_REG (QImode, HARD_D_REGNUM) : \
++	((MODE == HImode) && !((CUM) & (CUM_STACK_ONLY | CUM_X_MASK))) ?  \
++		gen_rtx_REG (HImode, HARD_X_REGNUM) : m6809_function_arg_on_stack (&CUM))
++
++/* Output assembler code to FILE to increment profiler label # LABELNO
++   for profiling a function entry.  */
++#define FUNCTION_PROFILER(FILE, LABELNO) \
++   fprintf (FILE, "\tldd\t#LP%u\n\tjsr\tmcount\n", (LABELNO));
++
++/* Stack pointer must be correct on function exit */
++#define EXIT_IGNORE_STACK 0
++
++/*****************************************************************************
++**
++** Trampolines for Nested Functions
++**
++*****************************************************************************/
++
++/* Length in units of the trampoline for entering a nested function.  */
++#define TRAMPOLINE_SIZE 7
++
++/*--------------------------------------------------------------
++	Addressing modes,
++	and classification of registers for them.
++--------------------------------------------------------------*/
++
++/* 6809 has postincrement and predecrement addressing modes */
++#define HAVE_POST_INCREMENT  1
++#define HAVE_PRE_DECREMENT  1
++
++/* Whether or not to use index registers is configurable.
++ * Experiments show that things work better when this is off, so
++ * that's the way it is for now. */
++#undef USE_INDEX_REGISTERS
++
++
++/* Macros to check register numbers against specific register classes.  */
++#define REG_VALID_FOR_BASE_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && A_REGNO_P (REGNO))
++
++/* MC6809 index registers do not allow scaling, */
++/* but there is "accumulator-offset" mode. */
++#ifdef USE_INDEX_REGISTERS
++#define REG_VALID_FOR_INDEX_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && I_REGNO_P (REGNO))
++#else
++#define REG_VALID_FOR_INDEX_P(REGNO) 0
++#endif
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_BASE_P (REGNO) \
++	|| (REGNO) == FRAME_POINTER_REGNUM \
++	|| (REGNO) == HARD_FRAME_POINTER_REGNUM \
++	|| (REGNO) == ARG_POINTER_REGNUM \
++	|| (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_INDEX_P (REGNO) \
++	|| (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_BASE_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_INDEX_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_BASE_STRICT_P (REGNO)
++
++#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_INDEX_STRICT_P (REGNO)
++
++#define REG_OK_FOR_BASE_STRICT_P(X)     REGNO_OK_FOR_BASE_STRICT_P (REGNO (X))
++#define REG_OK_FOR_BASE_NONSTRICT_P(X)  REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_STRICT_P(X)    REGNO_OK_FOR_INDEX_STRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_NONSTRICT_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (X))
++
++#ifndef REG_OK_STRICT
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_NONSTRICT_P(X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_NONSTRICT_P(X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#else
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_STRICT_P (X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_STRICT_P (X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#endif
++
++/* Maximum number of registers that can appear in a valid memory address */
++#ifdef USE_INDEX_REGISTERS
++#define MAX_REGS_PER_ADDRESS 2
++#else
++#define MAX_REGS_PER_ADDRESS 1
++#endif
++
++/* 1 if X is an rtx for a constant that is a valid address.
++ * We allow any constant, plus the sum of any two constants (this allows
++ * offsetting a symbol ref) */
++#define CONSTANT_ADDRESS_P(X) \
++	((CONSTANT_P (X)) \
++	|| ((GET_CODE (X) == PLUS) \
++	      && (CONSTANT_P (XEXP (X, 0))) && (CONSTANT_P (XEXP (X, 1)))))
++
++/* Nonzero if the constant value X is a legitimate general operand.
++   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
++/* Any single-word constant is ok; the only contexts
++   allowing general_operand of mode DI or DF are movdi and movdf. */
++#define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
++
++/* Nonzero if the X is a legitimate immediate operand in PIC mode. */
++#define LEGITIMATE_PIC_OPERAND_P(X)	!symbolic_operand (X, VOIDmode)
++
++/*--------------------------------------------------------------
++	Test for valid memory addresses
++--------------------------------------------------------------*/
++/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
++   that is a valid memory address for an instruction.
++   The MODE argument is the machine mode for the MEM expression
++   that wants to use this address. */
++
++/*--------------------------------------------------------------
++   Valid addresses are either direct or indirect (MEM) versions
++   of the following forms.
++	constant		N
++	register		,X
++	constant indexed	N,X
++	accumulator indexed	D,X
++	auto_increment		,X++
++	auto_decrement		,--X
++--------------------------------------------------------------*/
++
++#define REGISTER_ADDRESS_P(X) \
++  (REG_P (X) && REG_OK_FOR_BASE_P (X))
++
++#define EXTENDED_ADDRESS_P(X) \
++    CONSTANT_ADDRESS_P (X) \
++
++#define LEGITIMATE_BASE_P(X) \
++  ((REG_P (X) && REG_OK_FOR_BASE_P (X))	\
++   || (GET_CODE (X) == SIGN_EXTEND			\
++       && GET_CODE (XEXP (X, 0)) == REG			\
++       && GET_MODE (XEXP (X, 0)) == HImode		\
++       && REG_OK_FOR_BASE_P (XEXP (X, 0))))
++
++#define LEGITIMATE_OFFSET_P(X) \
++    (CONSTANT_ADDRESS_P (X) || (REG_P (X) && REG_OK_FOR_INDEX_P (X)))
++
++/* 1 if X is the sum of a base register and an offset. */
++#define INDEXED_ADDRESS(X) \
++   ((GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 0)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 1))) \
++   || (GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 1)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 0))))
++
++#define STACK_REG_P(X) (REG_P(X) && REGNO(X) == HARD_S_REGNUM)
++
++#define STACK_PUSH_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == PRE_DEC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define STACK_POP_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == POST_INC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define PUSH_POP_ADDRESS_P(X) \
++    (((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
++	&& (LEGITIMATE_BASE_P (XEXP (X, 0))))
++
++/* Go to ADDR if X is a valid address. */
++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
++{ \
++  if (REGISTER_ADDRESS_P(X)) goto ADDR; \
++  if (PUSH_POP_ADDRESS_P (X)) goto ADDR; \
++  if (EXTENDED_ADDRESS_P (X)) goto ADDR; \
++  if (INDEXED_ADDRESS (X)) goto ADDR; \
++  if (MEM_P (X) && REGISTER_ADDRESS_P(XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && PUSH_POP_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && EXTENDED_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && INDEXED_ADDRESS (XEXP (X, 0))) goto ADDR; \
++}
++
++/*--------------------------------------------------------------
++	Address Fix-up
++--------------------------------------------------------------*/
++/* Go to LABEL if ADDR (a legitimate address expression)
++   has an effect that depends on the machine mode it is used for.
++	In the latest GCC, this case is already handled by the core code
++	so no action is required here. */
++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
++
++
++/*--------------------------------------------------------------
++	Miscellaneous Parameters
++--------------------------------------------------------------*/
++/* Specify the machine mode that this machine uses
++   for the index in the tablejump instruction.  */
++#define CASE_VECTOR_MODE Pmode
++
++/* Define this as 1 if `char' should by default be signed; else as 0.  */
++#define DEFAULT_SIGNED_CHAR 0
++
++/* This flag, if defined, says the same insns that convert to a signed fixnum
++   also convert validly to an unsigned one.  */
++#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
++
++/* Max number of bytes we can move from memory to memory/register
++   in one reasonably fast instruction.  */
++#define MOVE_MAX 2
++
++/* Int can be 8 or 16 bits (default is 16) */
++#define INT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Short is always 16 bits */
++#define SHORT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Size (bits) of the type "long" on target machine */
++#define LONG_TYPE_SIZE (TARGET_BYTE_INT ? 16 : 32)
++
++/* Size (bits) of the type "long long" on target machine */
++#define LONG_LONG_TYPE_SIZE 32
++
++/* Size (bits) of the type "char" on target machine */
++#define CHAR_TYPE_SIZE 8
++
++/* Size (bits) of the type "float" on target machine */
++#define FLOAT_TYPE_SIZE 32
++
++/* Size (bits) of the type "double" on target machine.
++ * Note that the C standard does not require that doubles
++ * hold any more bits than float.  Since the 6809 has so few
++ * registers, we cannot really support more than 32-bits. */
++#define DOUBLE_TYPE_SIZE 32 
++
++/* Size (bits) of the type "long double" on target machine */
++#define LONG_DOUBLE_TYPE_SIZE 32
++
++/* Define the type used for "size_t".  With a 64KB address space,
++ * only a 16-bit value here makes sense. */
++#define SIZE_TYPE (TARGET_BYTE_INT ? "long unsigned int" : "unsigned int")
++
++/* Likewise, the difference between two pointers is also a 16-bit
++ * signed value. */
++#define PTRDIFF_TYPE (TARGET_BYTE_INT ? "long int" : "int")
++
++/* Nonzero if access to memory by bytes is slow and undesirable.  */
++#define SLOW_BYTE_ACCESS 0
++
++/* Define if shifts truncate the shift count
++   which implies one can omit a sign-extension or zero-extension
++   of a shift count.  */
++#define SHIFT_COUNT_TRUNCATED 0
++
++/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
++   is done just by pretending it is already truncated.  */
++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
++
++/* It is as good to call a constant function address as to
++   call an address kept in a register. */
++#define NO_FUNCTION_CSE
++
++/* Specify the machine mode that pointers have.
++   After generation of rtl, the compiler makes no further distinction
++   between pointers and any other objects of this machine mode.  */
++#define Pmode HImode
++
++/* A function address in a call instruction
++   is a byte address (for indexing purposes)
++   so give the MEM rtx a byte's mode.  */
++#define FUNCTION_MODE HImode
++
++/* Define the cost of moving a value from a register in CLASS1
++ * to CLASS2, of a given MODE.
++ *
++ * On the 6809, hard register transfers are all basically equivalent.
++ * But soft register moves are treated more like memory moves. */
++#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
++	(((CLASS1 == M_REGS) || (CLASS2 == M_REGS)) ? 4 : 7)
++
++/* Define the cost of moving a value between a register and memory. */
++#define MEMORY_MOVE_COST(MODE, CLASS, IN) 5
++
++/* Check a `double' value for validity for a particular machine mode.  */
++
++#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
++  ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
++
++
++/*--------------------------------------------------------------
++	machine-dependent
++--------------------------------------------------------------*/
++/* Tell final.c how to eliminate redundant test instructions.  */
++
++/* Here we define machine-dependent flags and fields in cc_status
++   (see `conditions.h').  */
++
++/* Store in cc_status the expressions
++   that the condition codes will describe
++   after execution of an instruction whose pattern is EXP.
++   Do not alter them if the instruction would not alter the cc's.  */
++
++/* On the 6809, most of the insns to store in an address register
++   fail to set the cc's.  However, in some cases these instructions
++   can make it possibly invalid to use the saved cc's.  In those
++   cases we clear out some or all of the saved cc's so they won't be used.  */
++
++#define NOTICE_UPDATE_CC(EXP, INSN) \
++  notice_update_cc((EXP), (INSN))
++
++/*****************************************************************************
++**
++** pragma support
++**
++*****************************************************************************/
++
++#if 0
++#define REGISTER_TARGET_PRAGMAS() \
++do { \
++	extern void pragma_section PARAMS ((cpp_reader *)); \
++	c_register_pragma (0, "section", pragma_section); \
++} while (0)
++
++#endif
++
++/*--------------------------------------------------------------
++	ASSEMBLER FORMAT
++--------------------------------------------------------------*/
++
++#define FMT_HOST_WIDE_INT "%ld"
++
++/* Output to assembler file text saying following lines
++   may contain character constants, extra white space, comments, etc.  */
++#define ASM_APP_ON ";----- asm -----\n"
++
++/* Output to assembler file text saying following lines
++   no longer contain unusual constructs.  */
++#define ASM_APP_OFF ";--- end asm ---\n"
++
++/* Use a semicolon to begin a comment. */
++#define ASM_COMMENT_START "; "
++
++/* Output assembly directives to switch to section 'name' */
++#undef TARGET_ASM_NAMED_SECTION
++#define TARGET_ASM_NAMED_SECTION	m6809_asm_named_section
++
++#undef TARGET_HAVE_NAMED_SECTION
++#define TARGET_HAVE_NAMED_SECTION m6809_have_named_section
++
++/* Output before read-only data.  */
++#define TEXT_SECTION_ASM_OP (code_section_op)
++
++/* Output before writable data.  */
++#define DATA_SECTION_ASM_OP (data_section_op)
++
++/* Output before uninitialized data.  */
++#define BSS_SECTION_ASM_OP (bss_section_op)
++
++/* Support the ctors and dtors sections for g++.  */
++ 
++#undef CTORS_SECTION_ASM_OP
++#define CTORS_SECTION_ASM_OP    "\t.area .ctors"
++#undef DTORS_SECTION_ASM_OP
++#define DTORS_SECTION_ASM_OP    "\t.area .dtors"
++
++
++#undef DO_GLOBAL_CTORS_BODY
++#undef DO_GLOBAL_DTORS_BODY
++
++#define HAS_INIT_SECTION
++
++/* This is how to output an assembler line
++   that says to advance the location counter
++   to a multiple of 2**LOG bytes.  */
++
++#define ASM_OUTPUT_ALIGN(FILE,LOG) \
++  if ((LOG) > 1) \
++    fprintf (FILE, "\t.bndry %u\n", 1 << (LOG))
++
++/* The .set foo,bar construct doesn't work by default */
++#undef SET_ASM_OP
++#define ASM_OUTPUT_DEF(FILE, LABEL1, LABEL2)			\
++  do								\
++    {								\
++      fputc ('\t', FILE);					\
++      assemble_name (FILE, LABEL1);				\
++      fputs (" = ", FILE);					\
++      assemble_name (FILE, LABEL2);				\
++      fputc ('\n', FILE);					\
++    }								\
++  while (0)
++
++/* How to refer to registers in assembler output.
++   This sequence is indexed by compiler's hard-register-number (see above).  */
++#define MNAME(x) [SOFT_M0_REGNUM+(x)] = "*m" C_STRING(x) ,
++
++#define REGISTER_NAMES { \
++	[HARD_D_REGNUM]= "d", \
++	[HARD_X_REGNUM]= "x", \
++	[HARD_Y_REGNUM]= "y", \
++	[HARD_U_REGNUM]= "u", \
++	[HARD_S_REGNUM]= "s", \
++	[HARD_PC_REGNUM]= "pc", \
++	[HARD_A_REGNUM]= "a", \
++	[HARD_B_REGNUM]= "b", \
++	[HARD_CC_REGNUM]= "cc",\
++	[HARD_DP_REGNUM]= "dp", \
++	[SOFT_FP_REGNUM]= "soft_fp", \
++	[SOFT_AP_REGNUM]= "soft_ap", \
++	MNAME(0) MNAME(1) MNAME(2) MNAME(3) \
++	MNAME(4) MNAME(5) MNAME(6) MNAME(7) \
++	[HARD_RSVD1_REGNUM] = "-", \
++	[HARD_Z_REGNUM] = "z" /* bit 2 of CC */ }
++
++/*****************************************************************************
++**
++** Debug Support
++**
++*****************************************************************************/
++
++/* Default to DBX-style debugging */
++#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
++
++#define DBX_DEBUGGING_INFO
++
++#define DEFAULT_GDB_EXTENSIONS 0
++
++#define ASM_STABS_OP ";\t.stabs\t"
++#define ASM_STABD_OP ";\t.stabd\t"
++#define ASM_STABN_OP ";\t.stabn\t"
++
++#define DBX_CONTIN_LENGTH 54
++
++#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(ASMFILE, FILENAME) \
++do { \
++	const char *p = FILENAME; \
++	while ((p = strchr (p, '/')) != NULL) { \
++		p = FILENAME = p+1; \
++	} \
++  fprintf (ASMFILE, "%s", ASM_STABS_OP); \
++  output_quoted_string (ASMFILE, FILENAME); \
++  fprintf (ASMFILE, ",%d,0,0,", N_SO); \
++  assemble_name (ASMFILE, ltext_label_name); \
++  fputc ('\n', ASMFILE); \
++  switch_to_section (text_section); \
++  (*targetm.asm_out.internal_label) (ASMFILE, "Ltext", 0); \
++} while (0)
++
++/* With -g, GCC sometimes outputs string literals that are longer than
++ * the assembler can handle.  Without actual debug support, these are
++ * not really required.  Redefine the function to output strings to
++ * output as much as possible. */
++#define OUTPUT_QUOTED_STRING(FILE, STR) m6809_output_quoted_string (FILE, STR)
++
++/*****************************************************************************
++**
++** Output and Generation of Labels
++**
++*****************************************************************************/
++
++/* Prefixes for various assembly-time objects */
++
++#define REGISTER_PREFIX ""
++
++#define LOCAL_LABEL_PREFIX ""
++
++#define USER_LABEL_PREFIX "_"
++
++#define IMMEDIATE_PREFIX "#"
++
++/* This is how to output the definition of a user-level label named NAME,
++   such as the label on a static function or variable NAME.  */
++
++#define ASM_OUTPUT_LABEL(FILE,NAME) \
++do { \
++  if (section_changed) { \
++	  fprintf (FILE, "\n%s\n\n", code_section_op); \
++     section_changed = 0; \
++  } \
++  assemble_name (FILE, NAME); \
++  fputs (":\n", FILE); \
++} while (0)
++
++/* This is how to output the label for a function definition.  It
++   invokes ASM_OUTPUT_LABEL, but may examine the DECL tree node for
++	other properties. */
++#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
++  m6809_declare_function_name (FILE,NAME,DECL)
++
++/* This is how to output a command to make the user-level label
++    named NAME defined for reference from other files.  */
++
++#define GLOBAL_ASM_OP "\t.globl "
++
++/* This is how to output a reference to a user label named NAME. */
++#define ASM_OUTPUT_LABELREF(FILE,NAME) \
++  fprintf (FILE, "_%s", NAME)
++
++/* This is how to output a reference to a symbol ref
++ * Check to see if the symbol is in the direct page */
++#define ASM_OUTPUT_SYMBOL_REF(FILE,sym) \
++{ \
++	print_direct_prefix (FILE, sym); \
++	assemble_name (FILE, XSTR (sym, 0)); \
++}
++
++/* External references aren't necessary, so don't emit anything */
++#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)
++
++/* This is how to store into the string LABEL
++   the symbol_ref name of an internal numbered label where
++   PREFIX is the class of label and NUM is the number within the class.
++   This is suitable for output with `assemble_name'.  */
++#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
++  sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long int)NUM)
++
++/* This is how to output an assembler line defining an `int' constant.  */
++#define ASM_OUTPUT_INT(FILE,VALUE) \
++( fprintf (FILE, "\t.word "), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* Likewise for `char' and `short' constants.  */
++#define ASM_OUTPUT_SHORT(FILE,VALUE) \
++( fprintf (FILE, "\t.word "), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* This is how to output a string. */ 
++#define ASM_OUTPUT_ASCII(FILE,STR,SIZE) m6809_output_ascii (FILE, STR, SIZE)
++
++/* This is how to output an insn to push a register on the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
++   fprintf (FILE, "\tpshs\t%s\n", reg_names[REGNO])
++
++/* This is how to output an insn to pop a register from the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
++   fprintf (FILE, "\tpuls\t%s\n", reg_names[REGNO])
++
++/* This is how to output an element of a case-vector that is absolute. */
++
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++  fprintf (FILE, "\t.word L%u\n", VALUE)
++
++/* This is how to output an element of a case-vector that is relative. */
++
++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
++  fprintf (FILE, "\t.word L%u-L%u\n", VALUE, REL)
++
++
++/*****************************************************************************
++**
++** Assembler Commands for Alignment
++**
++*****************************************************************************/
++
++/* ASM_OUTPUT_SKIP is supposed to zero initialize the data.
++ * So use the .byte and .word directives instead of .blkb */
++#define ASM_OUTPUT_SKIP(FILE,SIZE) \
++  do { \
++    int __size = SIZE; \
++    while (__size > 0) { \
++      if (__size >= 2) \
++      { \
++        fprintf (FILE, "\t.word\t0\t;skip space %d\n", __size); \
++        __size -= 2; \
++      } \
++      else \
++      { \
++        fprintf (FILE, "\t.byte\t0\t;skip space\n"); \
++        __size--; \
++      } \
++    } \
++  } while (0)
++
++/* This says how to output an assembler line
++   to define a global common symbol.  */
++
++#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
++  do { \
++  switch_to_section (bss_section); \
++  fputs ("\t.globl\t", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fputs ("\n", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* This says how to output an assembler line
++   to define a local common symbol.  */
++
++#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
++do { \
++  switch_to_section (bss_section); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* Store in OUTPUT a string (made with alloca) containing
++   an assembler-name for a local static variable named NAME.
++   LABELNO is an integer which is different for each call.  */
++
++#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
++( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
++  sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long int)(LABELNO)))
++
++/* Print an instruction operand X on file FILE.
++   CODE is the code from the %-spec for printing this operand.
++   If `%z3' was used to print operand 3, then CODE is 'z'. */
++#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
++
++/* Print a memory operand whose address is X, on file FILE. */
++#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
++
++/* Don't let stack pushes build up too much. */
++#define MAX_PENDING_STACK 8
++
++/* Define values for builtin operations */
++enum m6809_builtins
++{
++	M6809_SWI,
++	M6809_SWI2,
++	M6809_SWI3,
++	M6809_CWAI,
++	M6809_SYNC,
++	M6809_ADD_CARRY,
++	M6809_SUB_CARRY,
++	M6809_ADD_DECIMAL,
++	M6809_NOP,
++	M6809_BLOCKAGE
++};
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.md gcc-4.6.4/gcc/config/m6809/m6809.md
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.md	2015-07-20 22:05:21.702720231 -0600
+@@ -0,0 +1,2358 @@
++;; GCC machine description for Motorola 6809
++;; Copyright (C) 1989, 2005, 2006, 2007, 2008,
++;; 2009 Free Software Foundation, Inc.
++;;
++;; Mostly by Brian Dominy (brian@oddchange.com) with substantial renovations
++;; by William Astle (lost@l-w.ca).
++;;
++;; Based on earlier work by Tom Jones (jones@sal.wisc.edu) and
++;; Matthias Doerfel (msdoerfe@informatik.uni-erlangen.de)
++;;
++;; 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/>.
++;;
++;; General information:
++;; --------------------
++;; * This backend is mostly a rewrite from earlier (3.1.1 and before)
++;; versions.
++;;
++;; * The 'A' and 'B' registers are treated as a single register by the
++;; register allocator; hence, the instruction templates assume that
++;; both can be modified if either one is available for use.  No
++;; attempt is made to split instructions to refer to a particular half
++;; of the register.  It is always referred to as the 'D' register, even
++;; in QImode (when it will be displayed as 'B').
++;;
++;; * There is full support for proper branch instruction generation,
++;; based on instruction lengths.  However, many instruction patterns
++;; are still overloaded to emit lots of real instructions, which can
++;; make the length calculation difficult; in those cases, I've tried
++;; to be pessimistic and assume the worst-case.
++;;
++;; * The instruction type attributes are only defined for branch
++;; vs. non branch instructions for now, since there is seemingly no
++;; reason to define these for other types anyway.
++;;
++;; * The limited number of total registers presents the greatest
++;; challenge.  There are 'soft registers' -- memory locations
++;; used to simulate real regs -- which can be helpful.
++;;
++;; * Position-independent code (PIC) is supported and has been tested
++;; but not to the extent of absolute code generation.
++;;
++;; * All of the 6809 special opcodes, e.g. SWI and SYNC, are defined
++;; as UNSPEC instructions, and can be accessed from C code using
++;; __builtin_xxxx() style functions.
++;;
++;; What still needs to be done:
++;; ----------------------------
++;; * Replace remaining instances of (define_peephole) with
++;; (define_peephole2), or remove them completely if they are not
++;; matching anyway.  Add more peepholes for things actually encountered.
++;;
++;; * Indexing addressing can lead to crashes in complex functions when
++;; register pressure is high.  Only the 'D' register can actually be
++;; used as an index register, and its demand by other instructions
++;; can sometimes mean that it is impossible to satisfy constraints.
++;; Currently, indexing is completely disabled to avoid these types
++;; of problems, although code is slightly more inefficient in some
++;; working cases.
++;;
++;; * 32-bit math is terribly inefficient.
++;;
++
++
++;;--------------------------------------------------------------------
++;;-  Constants
++;;--------------------------------------------------------------------
++
++;
++; Define constants for hard register numbers.
++;
++(define_constants [
++  (HARD_RSVD1_REGNUM 0)
++  (HARD_X_REGNUM 1) (HARD_Y_REGNUM 2) (HARD_U_REGNUM 3)
++  (HARD_S_REGNUM 4) (HARD_PC_REGNUM 5) (HARD_D_REGNUM 6)
++  (HARD_Z_REGNUM 7)
++  (HARD_A_REGNUM 8) (HARD_B_REGNUM 9)
++  (HARD_CC_REGNUM 10) (HARD_DP_REGNUM 11)
++  (SOFT_FP_REGNUM 12) (SOFT_AP_REGNUM 13)
++  (SOFT_M0_REGNUM 14) (SOFT_M1_REGNUM 15)
++  (SOFT_M2_REGNUM 16) (SOFT_M3_REGNUM 17)
++])
++
++
++;
++; The range in which a short branch insn can be used.
++;
++(define_constants [
++  (MIN_SHORT_BRANCH_OFFSET -127)
++  (MAX_SHORT_BRANCH_OFFSET 128)
++])
++
++
++;
++; The lengths of various types of real 6809 instructions.
++;
++; By default, ordinary insns are 4 bytes long.  This is often not
++; right, and the insn patterns below will redefine this to the
++; correct value.
++;
++; Branch instruction lengths (conditional and unconditionals) are
++; well known and declared here.  The short insns are used when the
++; offset is within the range declared above (between MIN_SHORT
++; and MAX_SHORT) ; otherwise the long form is used.
++;
++(define_constants [
++  (DEFAULT_INSN_LENGTH 4)
++  (SHORT_CBRANCH_LENGTH 2)
++  (LONG_CBRANCH_LENGTH 4)
++  (SHORT_BRANCH_LENGTH 2)
++  (LONG_BRANCH_LENGTH 3)
++])
++
++
++;
++; Constants for insn cycle counts.
++; Note that these counts all assume 1-byte opcodes.  2-byte
++; opcodes require 1 extra cycles for fetching the extra byte.
++;
++(define_constants [
++  ;; The default insn length, when it cannot be calculated.
++  ;; Take a conservative approach and estimate high.
++  (DEFAULT_INSN_CYCLES 10)
++
++  ;; Cycle counts for ALU and load operations.
++  (ALU_INHERENT_CYCLES 2)
++  (ALU_IMMED_CYCLES 2)
++  (ALU_DIRECT_CYCLES 4)
++  (ALU_INDEXED_BASE_CYCLES 4)
++  (ALU_EXTENDED_CYCLES 5)
++
++  ;; If an ALU operation is on a 16-bit register (D), then
++  ;; add this number of cycles to the total count.
++  (ALU_16BIT_CYCLES 2)
++
++  ;; A load of a 16-bit register incurs this extra amount.
++  (LOAD_16BIT_CYCLES 1)
++
++  ;; Cycle counts for memory-only operations (bit shifts, clear, test)
++  (MEM_DIRECT_CYCLES 6)
++  (MEM_INDEXED_BASE_CYCLES 6)
++  (MEM_EXTENDED_CYCLES 7)
++
++  ;; Cycle count for any reg-reg transfer (regardless of size)
++  (EXG_CYCLES 8)
++  (TFR_CYCLES 6)
++
++  ;; Cycle count for a condition code update (andcc/orcc)
++  (CC_CYCLES 3)
++
++  (JMP_DIRECT_CYCLES 3)
++  (JMP_INDEXED_BASE_CYCLES 3)
++  (JMP_EXTENDED_CYCLES 4)
++
++  (JSR_DIRECT_CYCLES 7)
++  (JSR_INDEXED_BASE_CYCLES 7)
++  (JSR_EXTENDED_CYCLES 8)
++
++  (LEA_BASE_CYCLES 4)
++
++  ;; Cycle count for a psh/pul operations.  Add to this the
++  ;; total number of bytes moved for the correct count.
++  (PSH_PUL_CYCLES 5)
++
++  ;; Miscellaneous cycle counts
++  (CWAI_CYCLES 20)
++  (MUL_CYCLES 11)
++  (NOP_CYCLES 2)
++  (RTI_CYCLES 15)
++  (RTS_CYCLES 5)
++  (SWI_CYCLES 20)
++  (SYNC_CYCLES 4)
++])
++
++
++;
++; An enumeration of values for each "unspec"; i.e. unspecified
++; instruction.  These represent insns that are meaningful on the
++; 6809 but which have no intrinsic meaning to GCC itself.
++; These insns can be generated explicitly using the __builtin_xxx
++; syntax; they are also implicitly generated by the backend
++; as needed to implement other insns.
++;
++(define_constants [
++  (UNSPEC_BLOCKAGE 0)
++  (UNSPEC_PUSH_RS 1)
++  (UNSPEC_POP_RS 2)
++  (UNSPEC_SWI 3)
++  (UNSPEC_CWAI 4)
++  (UNSPEC_ADD_CARRY 5)
++  (UNSPEC_SUB_CARRY 6)
++  (UNSPEC_SYNC 7)
++  (UNSPEC_ADD_DECIMAL 8)
++])
++
++
++;;--------------------------------------------------------------------
++;;-  Predicates
++;;--------------------------------------------------------------------
++
++(include "predicates.md")
++
++;;--------------------------------------------------------------------
++;;-  Attributes
++;;--------------------------------------------------------------------
++
++;;
++;; The type attribute is used to distinguish between different
++;; types of branch instructions, so that their lengths can be
++;; calculated correctly.
++;;
++(define_attr "type" "branch,cbranch,unknown" (const_string "unknown"))
++
++;;
++;; The length of a branch instruction is calculated based on how
++;; far away the branch target is.  Lengths of other insns default
++;; to 4.  set_attr is used in instruction templates to specify
++;; the length when it is known exactly.  When not sure, err on
++;; the high side to avoid compile errors.
++;;
++(define_attr "length" ""
++  (cond [
++    (eq_attr "type" "branch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_BRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_BRANCH_LENGTH)
++          (const_int SHORT_BRANCH_LENGTH)))
++    (eq_attr "type" "cbranch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_CBRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_CBRANCH_LENGTH)
++          (const_int SHORT_CBRANCH_LENGTH)))
++  ] (const_int DEFAULT_INSN_LENGTH)))
++
++
++;;
++;; The default attributes for 'asm' statements.
++;; The default length is the longest possible single 6809 instruction,
++;; which is 5 bytes.  GCC will automatically multiply this by the
++;; number of real insns contained in an asm statement.
++;;
++(define_asm_attributes
++  [(set_attr "length" "5")
++   (set_attr "type" "unknown")])
++
++;;
++;; An attribute for the number of cycles that it takes an instruction
++;; to execute.
++;;
++(define_attr "cycles" "" (const_int DEFAULT_INSN_CYCLES))
++
++
++;;--------------------------------------------------------------------
++;;- Instruction patterns.  When multiple patterns apply,
++;;- the first one in the file is chosen.
++;;-
++;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
++;;-
++;;- Note: NOTICE_UPDATE_CC in m6809.h handles condition code updates
++;;- for most instructions.
++;;--------------------------------------------------------------------
++
++;;--------------------------------------------------------------------
++;;-  Test
++;;--------------------------------------------------------------------
++
++;; cmpx is 3 bytes, not 4
++(define_insn "*tsthi_x"
++  [(set (cc0) (match_operand:HI 0 "register_operand_x" "v"))]
++  ""
++  "cmpx\t#0"
++  [(set_attr "length" "3")])
++
++;; subd #0 is 3 bytes, better than cmpd #0 which is 4 bytes
++(define_insn "*tsthi_d"
++  [(set (cc0) (match_operand:HI 0 "register_operand_d" "d"))]
++  ""
++  "subd\t#0"
++  [(set_attr "length" "3")])
++
++(define_insn "*tsthi"
++  [(set (cc0) (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "cmp%0\t#0"
++   [(set_attr "length" "4")])
++
++(define_insn "*bitqi3"
++  [(set (cc0)
++    (and:QI (match_operand:QI 0 "register_operand" "%q")
++      (match_operand:QI 1 "general_operand" "mi")))]
++  ""
++  "bit%0\t%1"
++  [(set_attr "length" "3")])
++
++
++(define_insn "tstqi"
++  [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "q,mt"))]
++  ""
++  "@
++   tst%0
++   tst\t%0"
++   [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Compare instructions
++;;--------------------------------------------------------------------
++
++;; - cmphi for register to memory or register compares
++(define_insn "cmphi"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 0 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 1 "general_operand" "mi, da,  dU")))]
++  ""
++{
++  if ((REG_P (operands[0])) && (REG_P (operands[1]))) {
++    output_asm_insn ("pshs\t%1\t;cmphi: R:%1 with R:%0", operands);
++    return "cmp%0\t,s++\t;cmphi:";
++  }
++  if (GET_CODE (operands[0]) == REG)
++    return "cmp%0\t%1\t;cmphi:";
++  else {
++    cc_status.flags |= CC_REVERSED;
++    return "cmp%1\t%0\t;cmphi:(R)";
++  }
++}
++  [(set_attr "length" "5,5,7")])
++
++
++(define_insn "cmpqi"
++  [(set (cc0)
++    (compare (match_operand:QI 0 "whole_general_operand" "q,q, q,O,mt,K")
++    (match_operand:QI 1 "whole_general_operand"          "O,mt,K,q,q, q")))]
++  ""
++{
++    if (REG_P (operands[0]) && !M_REG_P (operands[0]))
++    {
++      if (operands[1] == const0_rtx)
++        return "tst%0\t;cmpqi:(ZERO)";
++      else
++        return "cmp%0\t%1\t;cmpqi:";
++    }
++    else
++    {
++      cc_status.flags |= CC_REVERSED;
++
++      if (operands[0] == const0_rtx)
++        return "tst%1\t;cmpqi:(RZERO)";
++      else
++        return "cmp%1\t%0\t;cmpqi:(R)";
++    }
++}
++   [(set_attr "length" "1,3,2,1,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- Compare/branch pattern
++;;--------------------------------------------------------------------
++
++(define_expand "cbranchhi4"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 1 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 2 "general_operand" "mi, da,  dU")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++(define_expand "cbranchqi4"
++  [(set (cc0)
++    (compare
++      (match_operand:QI 1 "whole_general_operand" "q,q, q,O,mt,K")
++      (match_operand:QI 2 "whole_general_operand" "O,mt,K,q,q, q")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++;;--------------------------------------------------------------------
++;;-  Move
++;;--------------------------------------------------------------------
++
++; this looks good (obviously not finished) but I still see 'movsi'
++; places in udivsi3 where it's broken
++; (define_insn "pushsi1"
++;   [(set (mem:SI (pre_dec (reg:HI HARD_S_REGNUM)))
++;         (match_operand:SI 0 "general_operand" "o"))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int -4))) ]
++;   ""
++;   "; pushsi %0"
++;    [(set_attr "length" "12")])
++;
++; (define_insn "popsi1"
++;   [(set (match_operand:SI 0 "general_operand" "=o")
++;         (mem:SI (post_inc (reg:HI HARD_S_REGNUM))))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int 4))) ]
++;   ""
++;   "; popsi %0"
++;    [(set_attr "length" "12")])
++
++; (define_insn "movsi"
++;   [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
++;         (match_operand:SI 1 "general_operand"      " oi"))]
++;   ""
++;   "; movsi %0 <- %1"
++;    [(set_attr "length" "1")])
++
++; this doesn't work
++; (define_expand "movsi"
++;   [(parallel [
++;      (set (match_operand:SI 0 "nonimmediate_operand" "")
++;           (match_operand:SI 1 "general_operand" ""))
++;      (clobber (match_scratch:HI 2 ""))])]
++;   ""
++; {
++;   rtx insn;
++;   if (STACK_PUSH_P (operands[0]) || STACK_POP_P (operands[1]))
++;   {
++;     REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
++;   }
++;   insn = emit_move_multi_word (SImode, operands[0], operands[1]);
++;   DONE;
++; })
++
++
++(define_expand "movhi"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++{
++  /* One of the ops has to be in a register prior to reload */
++  if (!register_operand (operand0, HImode) &&
++      !register_operand (operand1, HImode))
++    operands[1] = copy_to_mode_reg (HImode, operand1);
++})
++
++;;; Try a splitter to handle failure cases where we try to move
++;;; an immediate constant (zero usually) directly to memory.
++;;; This absolutely requires an intermediate register.
++(define_split
++  [(set (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "immediate_operand"  ""))
++   (clobber (match_operand:HI 2 "register_operand" ""))]
++  ""
++  [(set (match_dup 2) (match_dup 1))
++   (set (match_dup 0) (match_dup 2))]
++  "")
++
++
++;;; This would be a nice method for loading from a word array,
++;;; but it is never generated because the combiner cannot merge
++;;; more than 3 instructions (there are four here).  This is
++;;; perhaps better done via a peephole.
++(define_insn "*movhi_array_load"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=da")
++    (mem:HI (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B")) (const_int 1))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;abx\;ld%0\t,x"
++   [(set_attr "length" "7")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movhi_push"
++  [(set (match_operand:HI 0 "push_operand" "=m")
++    (match_operand:HI 1 "register_operand" "U"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++(define_insn "*movhi_pic_symbolref"
++  [(set (match_operand:HI 0 "register_operand" "=a")
++    (match_operand:HI 1 "symbolic_operand" ""))]
++  "flag_pic"
++  "lea%0\t%c1,pcr"
++   [(set_attr "length" "4")])
++
++
++(define_insn "*movhi_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,d,a,ad,mu")
++    (match_operand:HI 1 "general_operand"          " a,a,d,miu,ad"))]
++  ""
++  "@
++   lea%0\t,%1
++   tfr\t%1,%0
++   tfr\t%1,%0
++   ld%0\t%1
++   st%1\t%0"
++   [(set_attr "length" "2,2,2,*,*")])
++
++
++;;; Generated by the combiner to merge an address calculation with
++;;; a byte load.  We can use the 'abx' instruction here.
++(define_insn "*movqi_array_load"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (mem:QI (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B"))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;ld%0\t,x"
++   [(set_attr "length" "6")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movqi_push"
++  [(set (match_operand:QI 0 "push_operand" "=m")
++    (match_operand:QI 1 "register_operand" " q"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++;;; Optimize the move of a byte from the stack using the puls instruction
++;;; instead of a store with post-decrement.
++(define_insn "movqi_pop"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (match_operand:QI 1 "pop_operand" "m"))]
++  ""
++  "puls\t%0"
++  [(set_attr "length" "2")])
++
++
++;;- load low byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_lsb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,m,a,d, U") 1))]
++  ""
++  "@
++   \t;movlsbqihi: D->B
++   ld%0\t%L1\t;movlsbqihi: msb:%1 -> R:%0
++   tfr\t%1,d\t;movlsbqihi: R:%1 -> R:%0
++   stb\t%0\t;movlsbqihi: R:%1 -> %0
++   pshs\t%1\t;movlsbqihi: R:%1 -> R:%0\;leas\t1,s\;puls\t%0"
++   [(set_attr "length" "0,*,2,*,6")])
++
++
++;;- load high byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_msb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,O,a,m,d, U") 0))]
++  ""
++  "@
++   tfr\ta,b\t;movmsbqihi: D->B
++   clr%0\t\t;movmsbqihi: ZERO -> R:%0
++   tfr\t%1,d\t;movmsbqihi: R:%1 -> R:%0\;tfr\ta,b
++   ld%0\t%L1\t;movmsbqihi: lsb:%1 -> R:%0
++   sta\t%0\t;movmsbqihi: R:%1 -> %0
++   pshs\t%1\t;movmsbqihi: R:%1 -> R:%0\;puls\t%0\;leas\t1,s"
++  [(set_attr "length" "2,1,4,*,*,6")])
++
++
++(define_insn "*movqi_boolean"
++  [(set (reg:QI HARD_Z_REGNUM)
++    (match_operand:QI 0 "general_operand" "q,O,i,m"))]
++  ""
++  "@
++   tst%0
++   andcc\t#~4
++   orcc\t#4
++   tst\t%0")
++
++
++(define_insn "movqi"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,m,q,m,q,z")
++    (match_operand:QI 1 "general_operand"          " q,O,O,mi,q,z,q"))]
++  ""
++  "@
++   tfr\t%1,%0
++   clr%0
++   clr\t%0
++   ld%0\t%1
++   st%1\t%0
++   tfr\tcc,%0\;and%0\t#4
++   tst%0"
++   [(set_attr "length" "2,1,3,*,*,4,1")])
++
++
++;;--------------------------------------------------------------------
++;;-  Swap registers
++;;--------------------------------------------------------------------
++
++; Note: 8-bit swap is never needed so it is not defined.
++
++(define_insn "swaphi"
++  [(set (match_operand:HI 0 "register_operand" "+r")
++    (match_operand:HI 1 "register_operand" "+r"))
++   (set (match_dup 1) (match_dup 0))]
++  ""
++  "exg\t%1,%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int EXG_CYCLES))])
++
++
++(define_insn "bswaphi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
++  ""
++  "exg\ta,b"
++  [(set_attr "length" "2")])
++
++
++;;--------------------------------------------------------------------
++;;-  Extension and truncation insns.
++;;--------------------------------------------------------------------
++
++(define_insn "extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (sign_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "sex\t\t;extendqihi2: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++(define_insn "zero_extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (zero_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "clra\t\t;zero_extendqihi: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++;;--------------------------------------------------------------------
++;;- All kinds of add instructions.
++;;--------------------------------------------------------------------
++
++
++;;
++;; gcc's automatic version of addsi3 doesn't know about adcb,adca
++;; so it is MUCH less efficient.  Define this one ourselves.
++;;
++;; TODO - can't always get 'd' for the clobber... allow other registers
++;; as well and use exg d,R ... exg R,d around the code sequence to
++;; use others, at a price.  Also consider libcall for this when
++;; optimizing for size.
++;;
++(define_insn "addsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (plus:SI (match_operand:SI 1 "general_operand" "%o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (PLUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++; Increment of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int 1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("inc\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("inc\t%0\;__IL%=:", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Decrement of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_minus1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int -1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("tst\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("dec\t%0", xoperands);
++  output_asm_insn ("__IL%=:", xoperands);
++  output_asm_insn ("dec\t%1", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Allow the addition of an 8-bit quantity to a 16-bit quantity
++; using the LEAX B,Y addressing mode, where X and Y are both
++; index registers.  This will only get generated via the peephole
++; which removes a sign extension.
++(define_insn "*addhi_b"
++  [(set (match_operand:HI 0 "index_register_operand"       "=a")
++    (plus:HI(match_operand:HI 1 "index_register_operand"   "%a")
++    (match_operand:QI 2 "register_operand"                  "q")
++  ))]
++  ""
++  "lea%0\t%2,%1\t;addhi_b: R:%0 = R:%2 + R:%1"
++  [(set_attr "length" "*")])
++
++
++; Splitter for addhi pattern #5 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "memory_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   (set (reg:HI HARD_D_REGNUM)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 1)))
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   ]
++{
++})
++
++
++; Splitter for addhi pattern #7 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   (set (match_dup 0)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 0)))
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   ]
++{
++})
++
++
++; TODO - this is ugly.  During RTL generation, we don't know what registers
++; are available, so the multiple-insn sequences can only be solved
++; via 'define_split's during matching.  See andhi3 for an example.
++; Keep the constraints with ? modifiers to help reload pick the right
++; registers.
++;
++; The forms are:
++; 1. D += D, expand this into a shift instead. (rtx costs should be corrected
++; to avoid this even happening...)
++; 2. D += U, require U to be pushed to memory.  (Lots of patterns do this
++; now, is this a better way?)
++; 3. Best choice: 'addd'
++; 4. Next best choice: 'lea'
++; 5. Hybrid of 3 and 4
++; 6. Same as 4, not bad
++; 7. BAD, no D register at all
++; 8. 'lea', as good as 4.
++(define_insn "addhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"      "=d, d,  d,  a,?a, a,???T,a")
++    (plus:HI(match_operand:HI 1 "add_general_operand"   "%0, 0,  0,  d, 0, a, 0, a")
++    (match_operand:HI 2 "general_operand"               " 0, !U, mi, a, m, d, T, i")
++  ))]
++  ""
++  "@
++   lslb\t\t;addhi: R:%0 += R:%2\;rola\t\t;also R:%0 *= 2
++   pshs\t%2\t;addhi: R:%0 += R:%2\;add%0\t,s++
++   add%0\t%2
++   lea%0\t%1,%2
++   #
++   lea%0\t%2,%1
++   #
++   lea%0\t%a2,%1"
++   [(set_attr "length" "2,6,*,*,7,*,7,*")])
++
++
++(define_insn "addqi3_carry"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_ADD_CARRY))]
++  ""
++  "adc%0\t%2\t;addqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++; TODO: specifying 'A' for the first constraint, to force into the A register
++; is not working because of the way registers are currently set up.  This will
++; take some work to get right.  Thus the second alternative as a backup.
++(define_insn "addqi3_decimal"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=A,?q")
++    (unspec:QI [
++      (match_operand:QI 1 "general_operand"        "%0,0")
++      (match_operand:QI 2 "general_operand"        "mi,mi")] UNSPEC_ADD_DECIMAL))]
++  ""
++  "@
++   adda\t%2\;daa
++   tfr\t%0,a\;adda\t%2\;daa\;tfr\ta,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "addqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "=q,q,q,m,m,q")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "%0,0,0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " 0,I,N,I,N,mi")))]
++  ""
++  "@
++   asl%0\t\t;addqi: R:%0 = R:%0 + R:%0
++   inc%0
++   dec%0
++   inc\t%0
++   dec\t%0
++   add%0\t%2"
++  [(set_attr "length" "1,1,1,3,3,*")])
++
++
++;;--------------------------------------------------------------------
++;;- Subtract instructions.
++;;--------------------------------------------------------------------
++
++(define_insn "subsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (minus:SI (match_operand:SI 1 "general_operand" " o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (MINUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++(define_insn "subhi3"
++  [(set (match_operand:HI 0 "register_operand"      "=d,  d, a")
++    (minus:HI (match_operand:HI 1 "register_operand" "0,  0, 0")
++    (match_operand:HI 2 "general_operand"            "mi, ?U,n")))]
++  ""
++  "@
++   sub%0\t%2\t;subhi: R:%0 -= %2
++   pshs\t%2\t;subhi: R:%0 -= R:%2\;sub%0\t,s++
++   lea%0\t%n2,%1\t;subhi: R:%0 = R:%1 + %n2"
++   [(set_attr "length" "*,5,3")])
++
++
++(define_insn "subqi3_carry"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_SUB_CARRY))]
++  ""
++  "sbc%0\t%2\t;subqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++(define_insn "subqi3"
++  [(set (match_operand:QI 0 "register_operand"            "=q, q, !q, q")
++    (minus:QI (match_operand:QI 1 "whole_register_operand" "0, 0,  I, 0")
++    (match_operand:QI 2 "whole_general_operand"            "I, mi, 0, t")))]
++  ""
++  "@
++   dec%0
++   sub%0\t%2
++   dec%0\;neg%0
++   sub%0\t%2"
++   [(set_attr "length" "1,3,2,3")])
++
++
++;;--------------------------------------------------------------------
++;;- Multiply instructions.
++;;--------------------------------------------------------------------
++
++; TODO - merge these two instructions, using 'extend_operator' to match
++; either signed or zero extension.  Everything else is the same.
++(define_insn "mulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++      (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++      (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;mulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++(define_insn "umulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++    (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++    (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;umulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++; Expand a 16x16 multiplication into either a libcall or a shift.
++; If the second operand is a small constant, use the above form.
++; Otherwise, do a libcall.
++(define_expand "mulhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (mult:HI (match_operand:HI 1 "general_operand" "")
++    (match_operand:HI 2 "nonmemory_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "mulhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- Divide instructions.
++;;--------------------------------------------------------------------
++
++(define_expand "divhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (div:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "divhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "divqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (div:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "divqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "udivhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++     (udiv:HI (match_operand:HI 1 "register_operand" "")
++              (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "udivhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- mod
++;;--------------------------------------------------------------------
++
++(define_expand "modhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (mod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "modhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "modqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (mod:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "modqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "umodhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (umod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "umodhi3", operands, 2);
++  DONE;
++})
++
++
++
++;;--------------------------------------------------------------------
++;;- and, or, xor common patterns
++;;--------------------------------------------------------------------
++
++; Split a bitwise HImode into two QImode instructions, with one of
++; the sources in a pushable register.  The register is pushed onto
++; the stack and memory pop operands (,s+) are used in the QI forms.
++(define_split
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "register_operand" "")]))]
++  "reload_completed"
++  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 2))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++})
++
++; Split a bitwise HImode into two QImode instructions, with one
++; of the sources being a (MEM (MEM (...)); i.e. an indirect memory
++; reference.  This requires dereferencing the pointer into a
++; temporary register (X), which must be saved/restored around the
++; compute instructions.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (mem:HI (match_operand:HI 2 "memory_operand" ""))]))]
++  "reload_completed"
++  [
++   (set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 4))
++   (set (match_dup 4) (match_dup 2))
++   (set (match_dup 4) (mem:HI (match_dup 4)))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (match_dup 4) (mem:HI (post_inc:HI (reg:HI HARD_S_REGNUM))))
++   ]
++{
++  /* Use X for a temporary index register */
++  operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
++})
++
++
++; Split a bitwise HImode into two QImode instructions.  This is
++; the common case.  This handles splitting when neither of the
++; above two cases applies.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "general_operand" "")]))]
++  "reload_completed"
++  [(set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_A_REGNUM) (match_dup 4)]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_D_REGNUM) (match_dup 5)]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[4] = gen_rtx_const_high (operands[2]);
++    operands[5] = gen_rtx_const_low (operands[2]);
++  }
++  else if ((GET_CODE (operands[2]) == MEM)
++    && (GET_CODE (XEXP (operands[2], 0)) == MEM))
++  {
++    FAIL;
++  }
++  else
++  {
++    operands[4] = gen_highpart (QImode, operands[2]);
++    operands[5] = gen_lowpart (QImode, operands[2]);
++  }
++})
++
++; Below are the specific cases for each of the operators.
++; The QImode versions are the simplest and can be implemented
++; directly on the hardware.  The HImode cases are all output
++; using one of the above splitting techniques.
++
++;;--------------------------------------------------------------------
++;;- and
++;;--------------------------------------------------------------------
++
++(define_insn "andhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (and:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++;; it is not clear that this is correct
++(define_insn "*andqi_2"
++  [(set
++   (match_operand:QI 0 "register_operand" "=q")
++   (and:QI (match_operand:QI 1 "register_operand" "q")
++     (match_operand 2 "const_int_operand" "i")))]
++  ""
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[3] = GEN_INT(INTVAL(operands[2]) & 0xff);
++    return "and%0 %3";
++  }
++
++  return "and%0 %2";
++}
++  [(set_attr "length" "2")])
++
++(define_insn "andqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,qc")
++    (and:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   clr%0\t;andqi(ZERO)
++   \t;andqi(-1)
++   and%0\t%2
++   and%0\t%2"
++   [(set_attr "length" "1,0,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- or
++;;--------------------------------------------------------------------
++
++(define_insn "iorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (ior:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "iorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q, qc")
++    (ior:QI (match_operand:QI 1 "whole_register_operand" "%0,0, 0")
++    (match_operand:QI 2 "whole_general_operand"          " O,m,i")))]
++  ""
++  "@
++   \t;iorqi(ZERO)
++   or%0\t%2
++   or%0\t%2"
++   [(set_attr "length" "0,3,2")])
++
++;;--------------------------------------------------------------------
++;;- xor
++;;--------------------------------------------------------------------
++
++(define_insn "xorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (xor:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "xorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,q")
++    (xor:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   \t;xorqi(ZERO)
++   com%0\t;xorqi(-1)
++   eor%0\t%2
++   eor%0\t%2"
++   [(set_attr "length" "0,1,3,2")])
++
++;;--------------------------------------------------------------------
++;;-  Two's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "neghi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!a")
++    (neg:HI (match_operand:HI 1 "general_operand"   "0, 0")))]
++  ""
++  "@
++   nega\;negb\;sbca\t#0
++   exg\td,%0\;nega\;negb\;sbca\t#0\;exg\td,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "negqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   neg%0
++   neg\t%0"
++  [(set_attr "length" "1,3")])
++
++
++;;--------------------------------------------------------------------
++;;-  One's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "one_cmplhi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,?tm,???a")
++    (not:HI (match_operand:HI 1 "general_operand"   "0,  0,   0")))]
++  ""
++  "@
++   coma\;comb
++   com\t%0\;com\t%L0
++   exg\td,%0\;coma\;comb\;exg\td,%0"
++  [(set_attr "length" "2,6,6")])
++
++
++(define_insn "one_cmplqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   com%0
++   com\t%0"
++  [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Shifts/rotates
++;;--------------------------------------------------------------------
++
++(define_code_iterator bit_code [ashift ashiftrt lshiftrt])
++(define_code_attr bit_code_name [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
++
++(define_mode_iterator bit_mode [QI HI])
++(define_mode_attr bit_mode_name [(QI "qi3") (HI "hi3")])
++
++;; Emit RTL for any shift (handles all 3 opcodes and 2 mode sizes)
++
++(define_expand "<bit_code:bit_code_name><bit_mode:bit_mode_name>"
++  [(set (match_operand:bit_mode 0 "nonimmediate_operand" "")
++    (bit_code:bit_mode (match_operand:bit_mode 1 "general_operand" "")
++    (match_operand:bit_mode 2 "nonmemory_operand" "")))]
++  ""
++{
++})
++
++; Individual instructions implemented in the CPU.
++
++
++(define_insn "*ashift1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashift:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asl\t%0
++   asl%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*lshiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   lsr\t%0
++   lsr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*ashiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asr\t%0
++   asr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*rotate1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotate:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   rol\t%0
++   rol%0"
++  [(set_attr "length" "3,1")])
++
++
++(define_insn "*rotatert1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotatert:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   ror\t%0
++   ror%0"
++  [(set_attr "length" "3,1")])
++
++
++; A shift by 8 for D reg can be optimized by just moving
++; between the A/B halves, and then zero/sign extending or
++; filling in zeroes.
++; Because GCC does not understand that 'A' and 'D' refer to
++; the same storage location, we must use 'USE' throughout
++; to prevent deletion of 'unnecessary' instructions.
++; Similar optimization for MEM would require a scratch register
++; so is not done here.
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_A_REGNUM) (reg:QI HARD_D_REGNUM))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (const_int 0))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (lshiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (zero_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++
++; On the WPC hardware, there is a shift register that can be used
++; to compute (1<<n) efficiently in two instructions.  Note that this
++; form only works when using -mint8 though, because C will promote
++; to 'int' when doing this operation.  TODO : we need a 16-bit form too.
++(define_insn "ashlqi3_wpc"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (ashift:QI (match_operand:QI 1 "immediate_operand" "I")
++    (match_operand:QI 2 "general_operand" "q")))]
++  "TARGET_WPC"
++  "st%2\t0x3FF7\;ld%0\t0x3FF7"
++  [(set_attr "length" "6")])
++
++
++; Internal instructions for shifting by a constant.
++; Two forms are provided, one for QImode, one for HImode.
++; These are always split into the above instructions
++; (except for QImode forms that directly match one of the
++; above instructions, in which the condition will not
++; allow the splitter to match).
++
++(define_insn_and_split "<bit_code:bit_code_name>hi3_const"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=dm")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "immediate_operand"            "n")))]
++  ""
++  "#"
++  "reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++
++(define_insn_and_split "<bit_code:bit_code_name>qi3_const"
++  [(set (match_operand:QI 0 "nonimmediate_operand"     "=qm")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "immediate_operand"            "n")))]
++  "INTVAL (operands[2]) > 1"
++  "#"
++  "&& reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++; Internal instructions for shifting by a nonconstant.
++; These expand into complex assembly.
++
++(define_insn "<bit_code:bit_code_name>hi3_reg"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=d")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "20")])
++
++
++(define_insn "<bit_code:bit_code_name>qi3_reg"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "16")])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Jumps and transfers
++;;--------------------------------------------------------------------
++
++;;; The casesi pattern is normally *not* defined; see 'tablejump' instead.
++(define_expand "casesi"
++  [(match_operand:HI 0 "register_operand" "")   ; index to jump on
++   (match_operand:HI 1 "immediate_operand" "")   ; lower bound
++   (match_operand:HI 2 "immediate_operand" "")   ; total range
++   (match_operand 3 "" "")   ; table label
++   (match_operand 4 "" "")]  ; out of range label
++  "TARGET_BYTE_INT && TARGET_CASESI"
++{
++  m6809_do_casesi (operands[0], operands[1], operands[2],
++                   operands[3], operands[4]);
++  DONE;
++})
++
++(define_insn "tablejump_short_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (zero_extend:HI (match_operand:QI 0 "register_operand" "q")))))]
++  ""
++  "jmp\t[b,x]\t;tablejump_short_offset"
++  [(set_attr "length" "3")])
++
++(define_insn "tablejump_long_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (match_operand:HI 0 "register_operand" "d"))))]
++  ""
++  "jmp\t[d,x]\t;tablejump_long_offset"
++  [(set_attr "length" "3")])
++
++
++ ;; A tablejump operation gives the address in operand 0, with the
++ ;; CODE_LABEL for the table in operand 1.  The 'define_expand'
++ ;; shows the arguments as GCC presents them.  For a register
++ ;; operand, the assembly code is straightforward.  For a MEM,
++ ;; assumed to be a SYMBOL_REF, two forms are given, one normal
++ ;; and one for PIC mode.
++ (define_expand "tablejump"
++    [(parallel [
++     (set (pc) (match_operand:HI 0 "" ""))
++     (use (label_ref (match_operand 1 "" "")))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++    ""
++ {
++ })
++
++
++(define_insn "*tablejump_reg"
++   [(parallel [
++      (set (pc)
++         (match_operand:HI 0 "register_operand" "a"))
++      (use (label_ref (match_operand 1 "" "")))
++      (clobber (match_scratch:HI 2 ""))
++      ])]
++   ""
++   "jmp\t,%0"
++   [(set_attr "length" "3")])
++
++
++(define_insn "*tablejump_symbol"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "a")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++  "!flag_pic"
++{
++  output_asm_insn ("jmp\t[%a1,%0]", operands);
++  return "";
++}
++  [(set_attr "length" "4")])
++
++
++(define_insn "*tablejump_symbol_pic"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "d")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 "=&a"))
++     ])]
++  "flag_pic"
++{
++  output_asm_insn ("lea%2\t%a1,pcr", operands);
++  output_asm_insn ("ld%0\t%0,%2", operands);
++  output_asm_insn ("jmp\t%0,%2", operands);
++  return "";
++}
++  [(set_attr "length" "8")])
++
++
++(define_insn "indirect_jump"
++  [(set (pc)
++    (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "jmp\t,%0"
++  [(set_attr "length" "3")])
++
++
++(define_insn "jump"
++  [(set (pc) (label_ref (match_operand 0 "" "")))]
++  ""
++{
++  return output_branch_insn ( LABEL_REF, operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "branch"))])
++
++; Output assembly for a condition branch instruction.
++(define_insn "*cond_branch"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 0 "" "")) (pc)))]
++  ""
++{
++  return output_branch_insn ( GET_CODE(operands[1]),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++; Similar to above, but for a condition branch instruction that
++; had its operands reversed at some point.
++(define_insn "*cond_branch_reverse"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++      (pc) (label_ref (match_operand 0 "" ""))))]
++  ""
++{
++  return output_branch_insn ( reverse_condition (GET_CODE(operands[1])),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Calls
++;;--------------------------------------------------------------------
++
++;; Generate a call instruction for a function that does not
++;; return a value.  The expander is used during RTL generation.
++;; The instructions below are used during matching; only one
++;; of them will be used, depending on the type of function
++;; being called.  The different conditions are:
++;;
++;;    1) far_functionp - is this a far function?  Those need
++;;    to be output as indirect calls through a far-function
++;;    handler.
++;;
++;;    2) noreturn_functionp - if the function does not return,
++;;    we can use a 'jmp' instead of a 'jsr' to call it.
++;;
++;;    3) is PIC mode enabled?  If so, we'll always use
++;;    relative calls (lbsr or lbra).
++;;
++;; Note: not all combinations are fully supported, especially
++;; relating to PIC.
++;;
++;; The 'bsr' instruction is never generated.
++
++(define_expand "call"
++  [(call (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*call_nopic_far"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "far_functionp (operands[0])"
++{
++  output_far_call_insn (operands, 0);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++; PIC forms come first, and should only match
++; (MEM (SYMBOL_REF)).  Other MEM forms are treated as usual.
++(define_insn "*call_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && !noreturn_functionp (operands[0])"
++  "lbsr\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "!noreturn_functionp (operands[0])"
++  "jsr\t%0"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++(define_insn "*call_noreturn_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && noreturn_functionp (operands[0])"
++  "lbra\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_noreturn_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "noreturn_functionp (operands[0])"
++  "jmp\t%0"
++  [(set_attr "length" "3")])
++
++
++;;
++;; Same as above, but for functions that do return a value.
++;;
++(define_expand "call_value"
++  [(set (match_operand 0 "" "")
++    (call (match_operand:HI 1 "memory_operand" "")
++    (match_operand:HI 2 "general_operand" "")))]
++  ""
++  "")
++
++
++(define_insn "*call_value_far"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  "far_functionp (operands[1])"
++{
++  output_far_call_insn (operands, 1);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++(define_insn "*call_value_pic"
++  [(set (match_operand 0 "" "=gz")
++    (call (mem:HI (match_operand:HI 1 "symbolic_operand" ""))
++    (match_operand:HI 2 "general_operand" "g")))]
++  "flag_pic"
++  "lbsr\t%C1"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_value_nopic"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  ""
++  "jsr\t%1"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++
++;;
++;; How to generate an untyped call.
++;;
++(define_expand "untyped_call"
++  [(parallel [(call (match_operand 0 "" "")
++        (const_int 0))
++      (match_operand 1 "" "")
++      (match_operand 2 "" "")])]
++  ""
++{
++  int i;
++
++  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
++  for (i=0; i < XVECLEN (operands[2], 0); i++)
++  {
++    rtx set = XVECEXP (operands[2], 0, i);
++    emit_move_insn (SET_DEST (set), SET_SRC (set));
++  }
++  emit_insn (gen_blockage ());
++  DONE;
++})
++
++
++(define_expand "sibcall"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "")
++            (match_operand:HI 1 "immediate_operand" ""))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_1"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "m")
++            (match_operand:HI 1 "immediate_operand" "i"))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%0"
++  [(set_attr "length" "4")])
++
++
++(define_expand "sibcall_value"
++  [(parallel
++     [(set (match_operand 0 "" "")
++         (call (match_operand:HI 1 "memory_operand" "")
++               (match_operand:HI 2 "immediate_operand" "")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_value_1"
++  [(parallel
++     [(set (match_operand 0 "" "=gz")
++         (call (match_operand:HI 1 "memory_operand" "m")
++               (match_operand:HI 2 "immediate_operand" "i")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%1"
++  [(set_attr "length" "4")])
++
++
++;;--------------------------------------------------------------------
++;;-  Function Entry and Exit
++;;--------------------------------------------------------------------
++
++;; On entry to a function, the stack frame looks as follows:
++;; - return address (pushed by the caller)
++;; - saved registers
++;; - local variable storage
++;;
++;; If the function does not modify the stack after that, then
++;; any of these can be accessed directly as an offset from
++;; STACK_POINTER_REGNUM.  Otherwise, a frame pointer is required.
++;; In that case, the prologue must also initialize HARD_FRAME_POINTER_REGNUM
++;; and all references to the stack frame will use that as a base instead.
++;;
++(define_expand "prologue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_prologue_insns ();
++  DONE;
++})
++
++
++;; The function epilogue does exactly the reverse of the prologue,
++;; deallocating local variable space, restoring saved registers,
++;; and returning.
++;;
++;; For the 6809, the return may be 'rti' if the function was
++;; declared as an interrupt function, but is normally 'rts'.
++;;
++;; Also, as an optimization, the register restore and the 'rts'
++;; can be combined into a single instruction, by adding 'PC' to the
++;; list of registers to be restored.  This is only done if there are
++;; any saved registers, as 'rts' is more efficient by itself.
++;;
++(define_expand "epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (false);
++  DONE;
++})
++
++
++(define_expand "sibcall_epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (true);
++  DONE;
++})
++
++
++;; The RTS instruction
++(define_insn "return_rts"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () == 0"
++  "rts"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++(define_insn "return_puls_pc"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () != 0"
++  ""
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++;; The RTI instruction
++(define_insn "return_rti"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "m6809_current_function_has_type_attr_p (\"interrupt\")"
++  "rti"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTI_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;-  Unspecified instructions
++;;--------------------------------------------------------------------
++
++;; An instruction that has the effect of an unspec_volatile, but
++;; which doesn't require emitting any assembly code.
++(define_insn "blockage"
++  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
++  ""
++  ""
++  [(set_attr "length" "0")
++   (set (attr "cycles") (const_int 0))])
++
++
++;; Say how to push multiple registers onto the stack, using
++;; the 6809 'pshs' instruction.  The operand is a regset
++;; specifying which registers to push.
++;;
++;; The operand mode is not given intentionally, so as to allow
++;; any possible integer mode for the regset.
++;;
++;; See below for a peephole that can combine consecutive push
++;; instructions that qualify for merging.
++(define_insn "register_push"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "pshs\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++;; Say how to pop multiple registers from the stack, using
++;; the 6809 'puls' instruction.  The operand is the register
++;; bitset value.
++(define_insn "register_pop"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_POP_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "puls\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++(define_insn "m6809_swi"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "I,n")] UNSPEC_SWI)]
++  ""
++  "@
++   swi
++   swi%c0"
++  [(set_attr "length" "1,2")
++   (set (attr "cycles") (const_int SWI_CYCLES))])
++
++
++;; Generate the CWAI instruction
++(define_insn "m6809_cwai"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "")] UNSPEC_CWAI)]
++  ""
++  "cwai\t%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int CWAI_CYCLES))])
++
++
++;; Generate the SYNC instruction
++(define_insn "m6809_sync"
++  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
++  ""
++  "sync"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int SYNC_CYCLES))])
++
++
++;; Generate the NOP instruction
++(define_insn "nop"
++  [(const_int 0)]
++  ""
++  "nop"
++   [(set_attr "length" "1")
++   (set (attr "cycles") (const_int NOP_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;- Peepholes
++;;--------------------------------------------------------------------
++
++;;; Each peephole has an ID that is used for debugging.
++;;; Each peephole condition is bracketed by calls to
++;;; m6809_match_peephole2() also for debugging.
++(define_constants [
++  (PEEP_END 0)
++  (PEEP_COND 1)
++
++  (PEEP_STACK_STORE_INC 0)
++  (PEEP_STACK_CLEAR_INC 1)
++  (PEEP_LSRB_ADCB 2)
++  (PEEP_ABX 3)
++  (PEEP_ABX2 4)
++  (PEEP_INDEXED_INC 5)
++  (PEEP_MEM_DEC 6)
++  (PEEP_MEM_INC 7)
++  (PEEP_MEM_DEC_CMP 8)
++  (PEEP_PUSH2 9)
++  (PEEP_STORE_IMPLIES_CC 10)
++  (PEEP_DEC_IMPLIES_CC 11)
++  (PEEP_LEAB 12)
++  (PEEP_LDX_INDIRECT 13)
++  (PEEP_POP_JUNK 14)
++])
++
++
++;;; Optimize 'leas -1,s' followed by 'stb ,s'.  This can happen if the
++;;; function prologue needs to allocate stack space and 'b' is placed
++;;; into that local right away.  Combine the stack allocation with the
++;;; store using preincrement mode.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM)
++        (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM))
++        (match_operand:QI 0 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_STACK_STORE_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 0))]
++  "")
++
++
++;;; Same as above, but for a 'clr ,s' that follows the prologue.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM) (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM)) (const_int 0))]
++  "m6809_match_peephole2 (PEEP_STACK_CLEAR_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (const_int 0))]
++  "")
++
++
++;;; Merge two consecutive push instructions into a single register_push.
++(define_peephole2
++  [(set (match_operand 0 "push_operand" "")
++    (match_operand 1 "register_operand" ""))
++   (set (match_operand 2 "push_operand" "")
++    (match_operand 3 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_PUSH2, PEEP_COND)
++   && reload_completed
++   && GET_MODE (operands[1]) == GET_MODE (operands[3])
++   && m6809_can_merge_pushpop_p (UNSPEC_PUSH_RS, 1 << REGNO (operands[1]), 1 << REGNO (operands[3]))
++   && m6809_match_peephole2 (PEEP_PUSH2, PEEP_END)"
++  [(parallel [
++    (use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile [(match_dup 4)] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))])
++   (use (match_dup 1))
++   (use (match_dup 3))]
++{
++  operands[4] = gen_rtx_CONST_INT (QImode,
++    (1 << REGNO (operands[1])) | (1 << REGNO (operands[3])));
++})
++
++
++;;; Convert 'stX ,--s' into a push instruction.  Use the regset
++;;; notation, so that it may be combined with an adjacent regset.
++;;; TBD - this doesn't compile some code cleanly.
++;(define_peephole2
++;  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM)))
++;        (reg:HI HARD_X_REGNUM))]
++;  "reload_completed"
++;  [(parallel [
++;    (use (reg:HI HARD_S_REGNUM))
++;    (unspec_volatile [(match_dup 0)] UNSPEC_PUSH_RS)
++;    (clobber (reg:HI HARD_S_REGNUM))])]
++;{
++;  operands[0] = gen_rtx_CONST_INT (HImode, X_REGBIT);
++;})
++
++
++;;;
++;;; q = (q+1)/2 can be optimized as "lsrb; adcb".  This also
++;;; won't overflow when q=0xFF.
++;;; TODO : this form isn't accounting for promotion when
++;;; using 16-bit ints.
++;;;
++(define_peephole
++  [(set (reg:QI HARD_D_REGNUM)
++    (lshiftrt:QI (plus:HI (match_dup 0) (const_int 1)) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_LSRB_ADCB, PEEP_END)"
++  "lsrb\;adcb\t#0; peephole"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Optimize the case of following a register store with a test
++;; of reg or mem just moved.
++;;
++(define_peephole
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++  (match_operand:HI 1 "register_operand" "r"))
++   (set (cc0) (match_operand:HI 2 "general_operand" "g"))]
++  "m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_COND)
++   && (operands[2] == operands[0] || operands[2] == operands[1])
++   && m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_END)"
++  "st%1\t%0\t;movhi: R:%1 -> %0 w/ implied test of %2"
++  [(set_attr "length" "4")])
++
++
++;; Optimize a pair of SET instructions in which the second insn
++;; is the reverse of the first one.  I.e.
++;;
++;; A = B
++;;        ---->  A = B
++;; B = A
++;;
++;; The second insn is redundant.  Define two patterns, one for QI, one for HI.
++;; But don't do this if either is a VOLATILE MEM.
++(define_peephole2
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++        (match_operand:HI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;
++;; Optimize the sum of an 8-bit and 16-bit using the 'abx' instruction
++;; if B and X can be used.  Two patterns are provided to catch both
++;; X=X+D and X=D+X.
++;;
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++;;; Likewise, handle when B is scaled by 2 prior to the add.
++;;; Instead of shifting B in 4 cycles, just do the ABX a second
++;;; time, in only 3 cycles.
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Work around a compiler bug that generates bad code when copying
++;; between 32-bit memory addresses after a libcall.  The problem seen is
++;; that the source is MEM (REG X), but X is used as the reload register.
++;; The second half of the copy therefore fails.
++;;
++;; The solution is to switch the reload register to D, since that is guaranteed
++;; not to be in use right after a libcall.
++;;
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_operand:HI 0 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_operand:HI 1 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))]
++  "reload_completed"
++  [(set (reg:HI HARD_D_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_dup 0) (reg:HI HARD_D_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_dup 1) (reg:HI HARD_X_REGNUM))]
++  "")
++
++
++;; Turn "and then test" into a "bit test" operation.
++;; Provide variants for immediate and memory sources
++;; This is the most used peephople.
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "immediate_operand" "i")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "3")])
++; 
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "memory_operand" "m")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "4")])
++
++
++;; Turn a "decrement, then test" sequence into just a "decrement".
++;; The test can be omitted, since it is implicitly done.
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "")
++    (match_operand:QI 2 "immediate_operand" "")))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_DEC_IMPLIES_CC, PEEP_END)"
++  [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))]
++  "")
++
++
++;; Merge an indexed register increment with a previous usage.
++;; This is usually done automatically, but not always
++;; The 'use' should be optional; in all cases where this has been
++;; seen, it is required though.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++     (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (use (match_dup 0))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_INDEXED_INC, PEEP_END)"
++  [(set (match_dup 0) (mem:QI (post_inc:HI (match_dup 1))))
++   (use (match_dup 0))]
++  "")
++
++
++;;; Merge "ldX MEM; ldX ,X" into a single instruction using
++;;; the indirect mode.
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (match_operand:HI 0 "general_operand" "")))
++   (set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LDX_INDIRECT, PEEP_END)"
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (mem:HI (match_dup 0))))]
++  "")
++
++
++;;; Reorder a store followed by a unary operation on that memory
++;;; so that the unary is performed and then the store.  Consider
++;;; a binary shift operation, which will be decomposed into
++;;; identical single shifts, also.
++;;; TODO - recognize more than just 'ashift' here.
++(define_peephole2
++  [(set (match_operand:QI 0 "memory_operand" "")
++        (match_operand:QI 1 "register_operand" ""))
++   (set (match_dup 0)
++        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++  "reload_completed"
++  [(set (match_dup 1)
++        (ashift:QI (match_dup 1) (match_operand:QI 2 "immediate_operand")))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++;;; Likewise, reorder a unary MEM followed by a load, so that the load
++;;; is done first, then use the REG instead of the MEM.
++;;;(define_peephole2
++;;;  [(set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))
++;;;   (set (match_operand:QI 0 "register_operand" "")
++;;;        (match_operand:QI 1 "memory_operand" ""))]
++;;;  "reload_completed"
++;;;  [(set (match_dup 0) (match_dup 1))
++;;;   (set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++;;;  "")
++
++
++;;; Replace sex; leaX d,Y with leaX b,Y.
++;;;
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (match_operand:HI 1 "index_register_operand" "")
++                 (reg:HI HARD_D_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (reg:HI HARD_D_REGNUM)
++          (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++
++;;; Replace ldb; decb; stb; tstb with dec(mem).  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC_CMP, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace ldb; decb; stb with dec(mem); ldb.  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_INC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;; Replace "andb #N; cmpb #N; bhi" with "andb #N", if it can be proven
++;;; that the branch can never occur because of the limited range of B.
++;;; N must be a power of two for this to make sense.  This helps with
++;;; the default cases of switch statements on a value (x & N).
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++    (and:QI (match_dup 0) (match_operand:QI 1 "immediate_operand" "")))
++   (set (cc0)
++    (compare (match_dup 0) (match_dup 1)))
++   (set (pc) (if_then_else (gtu (cc0) (const_int 0)) (match_operand 2 "" "") (match_operand 3 "" "")))
++   ]
++  "reload_completed && power_of_two_p (INTVAL (operands[1]) + 1)"
++  [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
++  "")
++
++;;; Replace ldd <mem>; addd #1; std <mem> with 16-bit increment
++;;; of the mem, but only if D is dead.  Same for 16-bit decrement.
++;;; <mem> must be offsettable for the instruction to match.
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace a load or store using an indexed register, followed by an increment of that
++;;; register, with the combined form using autoincrement.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++   "reload_completed"
++  [(set (match_dup 0) (mem:QI (post_inc (match_dup 1))))]
++  "")
++
++
++;;- mode:emacs-lisp
++;;- comment-start: ";;- "
++;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
++;;- eval: (modify-syntax-entry ?[ "(]")
++;;- eval: (modify-syntax-entry ?] ")[")
++;;- eval: (modify-syntax-entry ?{ "(}")
++;;- eval: (modify-syntax-entry ?} "){")
++;-; vim: set ts=2:
++;-; vim: set expandtab:
++;-; vim: set filetype=lisp:
++;;- End:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.opt gcc-4.6.4/gcc/config/m6809/m6809.opt
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.opt	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.opt	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1,98 @@
++; Options for the M6809 port of the compiler
++;
++; Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
++; 02110-1301, USA.
++
++margcount
++Target Mask(ARGCOUNT)
++Push argument count
++
++mint8
++Target RejectNegative Mask(BYTE_INT)
++Use 8-bit integers
++
++mint16
++Target RejectNegative
++Use 16-bit integers InverseMask(BYTE_INT)
++
++mreg-args
++Target Mask(REG_ARGS)
++Use registers for function arguments
++
++mshort_size 
++Target RejectNegative Mask(SMALL_SIZE_T)
++Use 8-bit size_t
++
++mlong_size
++Target RejectNegative InverseMask(SMALL_SIZE_T)
++Use 16-bit size_t
++
++mdirect
++Target Mask(DIRECT)
++Enable direct addressing
++
++mwpc
++Target RejectNegative Mask(WPC)
++Enable WPC platform extensions
++
++mexperiment
++Target RejectNegative Mask(EXPERIMENT)
++Enable current experimental feature
++
++m6309
++Target RejectNegative Mask(6309)
++Enable Hitachi 6309 extensions
++
++mcasesi
++Target RejectNegative Mask(CASESI)
++Enable the casesi pattern
++
++mfar-code-page=
++Target RejectNegative Joined Var(far_code_page_option)
++Sets the far code page value for this compilation unit
++
++mcode-section=
++Target RejectNegative Joined Var(code_section_ptr)
++Sets the name of the section for code
++
++mdata-section=
++Target RejectNegative Joined Var(data_section_ptr)
++Sets the name of the section for initialized data
++
++mbss-section=
++Target RejectNegative Joined Var(bss_section_ptr)
++Sets the name of the section for uninitialized data
++
++mabi_version=
++Target RejectNegative Joined Var(m6809_abi_version_ptr)
++Sets the calling convention
++
++msoft-reg-count=
++Target RejectNegative Joined Var(m6809_soft_reg_count)
++Sets the number of soft registers that can be used
++
++mdret
++Target RejectNegative Mask(DRET)
++Put function call results in D, not X
++
++mfar-stack-param
++Target Mask(FAR_STACK_PARAM)
++Enable stack parameters to a farcall
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h gcc-4.6.4/gcc/config/m6809/m6809-protos.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809-protos.h	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1,94 @@
++/* GCC for 6809 : machine-specific function prototypes
++
++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 __M6809_PROTOS_H__
++#define __M6809_PROTOS_H__
++
++void 					print_options (FILE *file);
++void 					m6809_cpu_cpp_builtins (void);
++void 					m6809_override_options (void);
++void 					m6809_init_builtins (void);
++unsigned int 		m6809_get_live_regs (void);
++const char * 		m6809_get_regs_printable (unsigned int regs);
++unsigned int 		m6809_get_regs_size (unsigned int regs);
++int 					m6809_function_has_type_attr_p (tree decl, const char *);
++int 					m6809_current_function_has_type_attr_p (const char *);
++int 					prologue_epilogue_required (void);
++int 					noreturn_functionp (rtx x);
++void 					output_function_prologue (FILE *file, int size);
++void 					output_function_epilogue (FILE *file, int size);
++int 					check_float_value (enum machine_mode mode, double *d, int overflow);
++void 					m6809_asm_named_section (const char *name, unsigned int flags, tree decl);
++void 					m6809_asm_file_start (void);
++void              m6809_output_ascii (FILE *fp, const char *str, unsigned long size);
++void              m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl);
++void              m6809_reorg (void);
++int               m6809_current_function_is_void (void);
++int               m6809_can_merge_pushpop_p (int op, int regs1, int regs2);
++int               m6809_function_value_regno_p (unsigned int regno);
++void              emit_prologue_insns (void);
++void              emit_epilogue_insns (bool);
++void              m6809_conditional_register_usage (void);
++void              m6809_output_quoted_string (FILE *asm_file, const char *string);
++int               m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage);
++int               m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode);
++int               power_of_two_p (unsigned int n);
++void              m6809_do_casesi (rtx index, rtx lower_bound, rtx range, rtx table_label, rtx default_label);
++void              m6809_output_addsi3 (int rtx_code, rtx *operands);
++rtx               m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump);
++void              expand_constant_shift (int code, rtx dst, rtx src, rtx count);
++int               m6809_single_operand_operator (rtx exp);
++
++#ifdef TREE_CODE
++int m6809_init_cumulative_args (CUMULATIVE_ARGS cum, tree fntype, rtx libname);
++#endif /* TREE_CODE */
++
++#ifdef RTX_CODE
++void 					print_direct_prefix (FILE *file, rtx addr);
++void 					print_operand (FILE *file, rtx x, int code);
++void 					print_operand_address (FILE *file, rtx addr);
++void 					notice_update_cc (rtx exp, rtx insn);
++enum 					reg_class m6809_preferred_reload_class (rtx x, enum reg_class regclass);
++rtx 					gen_rtx_const_high (rtx r);
++rtx 					gen_rtx_const_low (rtx r);
++rtx 					gen_rtx_register_pushpop (int pop_flag, int regs);
++void 					emit_libcall_insns (enum machine_mode mode, const char *name, rtx *operands, int count);
++const char *		output_branch_insn (enum rtx_code code, rtx *operands, int length);
++void 					output_far_call_insn (rtx *operands, int has_return);
++void 					m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt);
++rtx 					m6809_expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore);
++const char *      far_functionp (rtx x);
++rtx               m6809_function_value (const tree valtype, const tree func);
++void              m6809_output_shift_insn (int rtx_code, rtx *operands);
++
++const char * m6809_get_decl_bank (tree decl);
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p);
++rtx m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum);
++const char * far_function_type_p (tree type);
++void m6809_asm_trampoline_template(FILE *f);
++bool m6809_frame_pointer_required (void);
++int m6809_can_eliminate (int from, int to);
++int m6809_initial_elimination_offset (int from, int to);
++void m6809_emit_move_insn (rtx dst, rtx src);
++void m6809_split_shift (enum rtx_code code, rtx *operands);
++bool m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED);
++
++
++#endif /* RTX_CODE */
++
++#endif /* __M6809_PROTOS_H__ */
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/predicates.md gcc-4.6.4/gcc/config/m6809/predicates.md
+--- gcc-4.6.4-clean/gcc/config/m6809/predicates.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/predicates.md	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1,78 @@
++;; Predicate definitions for Motorola 6809
++;; Copyright (C) 2006, 2007, 2008, 2009 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 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/>.
++
++;; whole_register_operand is like register_operand, but it
++;; does not allow SUBREGs.
++(define_predicate "whole_register_operand"
++  (and (match_code "reg")
++       (match_operand 0 "register_operand")))
++
++
++;; A predicate that matches any index register.  This can be used in nameless
++;; patterns and peepholes which need a 16-bit reg, but not D.
++(define_predicate "index_register_operand"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM || REGNO (op) == HARD_Y_REGNUM || REGNO (op) == HARD_U_REGNUM")))
++
++
++;; match only X
++(define_predicate "register_operand_x"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM")))
++
++;; match only D
++(define_predicate "register_operand_d"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_D_REGNUM")))
++
++
++;; Likwise, a replacement for general_operand which excludes
++;; SUBREGs.
++(define_predicate "whole_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")))
++
++
++(define_predicate "add_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")
++		 (match_test "REGNO (op) != SOFT_AP_REGNUM")))
++
++
++(define_predicate "shift_count_operand"
++  (and (match_code "const_int")
++     (and (match_operand 0 "const_int_operand")
++       (match_test "INTVAL (op) == 1 || INTVAL (op) == 8"))))
++
++
++;; A predicate that matches any bitwise logical operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "logical_bit_operator"
++	(ior (match_code "and") (match_code "ior") (match_code "xor")))
++
++
++;; A predicate that matches any shift or rotate operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "shift_rotate_operator"
++	(ior (match_code "ashift") (match_code "ashiftrt") (match_code "lshiftrt")
++	     (match_code "rotate") (match_code "rotatert")))
++
++
++(define_predicate "symbolic_operand" (match_code "symbol_ref"))
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-coco gcc-4.6.4/gcc/config/m6809/t-coco
+--- gcc-4.6.4-clean/gcc/config/m6809/t-coco	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-coco	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1,6 @@
++# For a few minor differences in code generation on the CoCo...
++T_CFLAGS = -DTARGET_COCO
++
++# For doing the startup differently on the CoCo...
++CRT0STUFF_T_CFLAGS += -Wa,--globalize-symbols -DTARGET_COCO
++# vim: set filetype=make:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-m6809 gcc-4.6.4/gcc/config/m6809/t-m6809
+--- gcc-4.6.4-clean/gcc/config/m6809/t-m6809	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-m6809	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1,64 @@
++
++# ranlib doesn't exist, so define it to 'true' to make it a no-op
++RANLIB_FOR_TARGET = true
++
++# Stubs for libgcc defined by m6809 are here
++LIB1ASMSRC = m6809/libgcc1.s
++
++# Here are the functions that are implemented within libgcc1.s
++LIB1ASMFUNCS = _mulhi3 _divhi3 _modhi3 _udivhi3 _umodhi3 \
++	_euclid _seuclid _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _softregs \
++	_ashlhi3 _ashrhi3 _lshrhi3
++
++# Flags to use when building libgcc.  IN_GCC does not seem necessary,
++# although the compile breaks without it.  -DDF=SF is required to set
++# the size of "double" to the same as the size of a "float".
++TARGET_LIBGCC2_CFLAGS =-DIN_GCC -Dinhibit_libc -DDF=SF -DLIBGCC2_HAS_SF_MODE=0 -DLIBGCC2_HAS_DF_MODE=0
++
++LIB2ADDEH =
++LIB2ADDEHSTATIC =
++LIB2ADDEHSHARED =
++
++LIBGCC2_DEBUG_CFLAGS =
++LIBGCC2_CFLAGS = -Os $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
++
++# Multilib information
++# This creates multiple versions of libgcc.a for each set of incompatible
++# -mxxx options.
++MULTILIB_OPTIONS  = fpic mdret
++MULTILIB_DIRNAMES =
++MULTILIB_MATCHES  =
++MULTILIB_EXCEPTIONS =
++EXTRA_MULTILIB_PARTS = crt0.o
++
++LIBGCC = stmp-multilib
++INSTALL_LIBGCC = install-multilib
++
++# We want fine grained libraries, so use the new code to build the
++# floating point emulation libraries.
++FPBIT = fp-bit.c
++
++fp-bit.c: $(srcdir)/config/fp-bit.c
++	echo '#define FLOAT' > fp-bit.c
++	echo '#define FLOAT_ONLY' >> fp-bit.c
++	echo '#define CMPtype HItype' >> fp-bit.c
++	echo '#define SMALL_MACHINE' >> fp-bit.c
++	echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
++	echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
++	echo '#endif' 		>> fp-bit.c
++	echo '#define DI SI'	>> fp-bit.c
++	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++
++# crt0.o is built from the following source file
++CRT0_S = $(srcdir)/config/m6809/crt0.S
++MCRT0_S = $(srcdir)/config/m6809/crt0.S
++
++# Flags to use when building crt0.o
++CRT0STUFF_T_CFLAGS += -fno-builtin -nostartfiles -nostdlib
++
++# Assemble startup files.
++$(T)crt0.o: $(CRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)crt0.o -x assembler-with-cpp $(CRT0_S)
++
++$(T)mcrt0.o: $(MCRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)mcrt0.o -x assembler-with-cpp $(MCRT0_S)
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-sim gcc-4.6.4/gcc/config/m6809/t-sim
+--- gcc-4.6.4-clean/gcc/config/m6809/t-sim	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-sim	2015-07-20 19:44:52.770843181 -0600
+@@ -0,0 +1 @@
++CRT0STUFF_T_CFLAGS += -DTARGET_SIM
+diff -urN gcc-4.6.4-clean/gcc/config.gcc gcc-4.6.4/gcc/config.gcc
+--- gcc-4.6.4-clean/gcc/config.gcc	2013-03-06 10:40:07.000000000 -0700
++++ gcc-4.6.4/gcc/config.gcc	2015-07-20 19:44:52.770843181 -0600
+@@ -375,6 +375,9 @@
+         cpu_type=m32r
+ 	extra_options="${extra_options} g.opt"
+         ;;
++m6809-*-*)
++        cpu_type=m6809
++        ;;
+ m68k-*-*)
+ 	extra_headers=math-68881.h
+ 	;;
+@@ -1706,6 +1709,12 @@
+ 		thread_file='posix'
+ 	fi
+ 	;;
++m6809-coco-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-coco"
++	;;
++m6809-*-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-sim"
++	;;
+ # m68hc11 and m68hc12 share the same machine description.
+ m68hc11-*-*|m6811-*-*)
+ 	tm_file="dbxelf.h elfos.h usegas.h newlib-stdint.h m68hc11/m68hc11.h"
+diff -urN gcc-4.6.4-clean/gcc/gcse.c gcc-4.6.4/gcc/gcse.c
+--- gcc-4.6.4-clean/gcc/gcse.c	2011-02-02 23:04:04.000000000 -0700
++++ gcc-4.6.4/gcc/gcse.c	2015-07-20 19:44:52.770843181 -0600
+@@ -833,7 +833,6 @@
+ 	      max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
+ 	      if (max_distance == 0)
+ 		return 0;
+-
+ 	      gcc_assert (max_distance > 0);
+ 	    }
+ 	  else
+diff -urN gcc-4.6.4-clean/gcc/libgcc2.c gcc-4.6.4/gcc/libgcc2.c
+--- gcc-4.6.4-clean/gcc/libgcc2.c	2011-01-03 13:52:22.000000000 -0700
++++ gcc-4.6.4/gcc/libgcc2.c	2015-07-20 19:44:52.770843181 -0600
+@@ -485,6 +485,7 @@
+ #endif
+ 
+ #ifdef L_bswapsi2
++#if MIN_UNITS_PER_WORD > 1
+ SItype
+ __bswapsi2 (SItype u)
+ {
+@@ -494,7 +495,9 @@
+ 	  | (((u) & 0x000000ff) << 24));
+ }
+ #endif
++#endif
+ #ifdef L_bswapdi2
++#if LONG_LONG_TYPE_SIZE > 32
+ DItype
+ __bswapdi2 (DItype u)
+ {
+@@ -508,6 +511,7 @@
+ 	  | (((u) & 0x00000000000000ffull) << 56));
+ }
+ #endif
++#endif
+ #ifdef L_ffssi2
+ #undef int
+ int
+@@ -1280,7 +1284,7 @@
+ UDWtype
+ __fixunssfDI (SFtype a)
+ {
+-#if LIBGCC2_HAS_DF_MODE
++#if LIBGCC2_HAS_DF_MODE || (FLT_MANT_DIG >= W_TYPE_SIZE)
+   /* Convert the SFtype to a DFtype, because that is surely not going
+      to lose any bits.  Some day someone else can write a faster version
+      that avoids converting to DFtype, and verify it really works right.  */
+@@ -1298,7 +1302,7 @@
+ 
+   /* Assemble result from the two parts.  */
+   return ((UDWtype) hi << W_TYPE_SIZE) | lo;
+-#elif FLT_MANT_DIG < W_TYPE_SIZE
++#else
+   if (a < 1)
+     return 0;
+   if (a < Wtype_MAXp1_F)
+@@ -1334,8 +1338,6 @@
+       return (DWtype)counter << shift;
+     }
+   return -1;
+-#else
+-# error
+ #endif
+ }
+ #endif
+diff -urN gcc-4.6.4-clean/gcc/longlong.h gcc-4.6.4/gcc/longlong.h
+--- gcc-4.6.4-clean/gcc/longlong.h	2011-10-04 01:28:50.000000000 -0600
++++ gcc-4.6.4/gcc/longlong.h	2015-07-20 19:44:52.770843181 -0600
+@@ -528,6 +528,11 @@
+ 	   : "cbit")
+ #endif /* __M32R__ */
+ 
++#if defined (__m6309__) || defined (__m6809__)
++#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
++#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctz (X))
++#endif
++
+ #if defined (__mc68000__) && W_TYPE_SIZE == 32
+ #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+   __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
+diff -urN gcc-4.6.4-clean/gcc/Makefile.in gcc-4.6.4/gcc/Makefile.in
+--- gcc-4.6.4-clean/gcc/Makefile.in	2013-04-01 02:32:34.000000000 -0600
++++ gcc-4.6.4/gcc/Makefile.in	2015-07-20 19:44:52.770843181 -0600
+@@ -2003,14 +2003,14 @@
+ 
+ # Compile the start modules crt0.o and mcrt0.o that are linked with
+ # every program
+-$(T)crt0.o: s-crt0 ; @true
+-$(T)mcrt0.o: s-crt0; @true
++crt0.o: s-crt0 ; @true
++mcrt0.o: s-crt0; @true
+ 
+ s-crt0:	$(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)crt0.o -c $(CRT0_S)
++	  -o crt0.o -c $(CRT0_S)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)mcrt0.o -c $(MCRT0_S)
++	  -o mcrt0.o -c $(MCRT0_S)
+ 	$(STAMP) s-crt0
+ #
+ # Compiling object files from source files.
+diff -urN gcc-4.6.4-clean/gcc/opth-gen.awk gcc-4.6.4/gcc/opth-gen.awk
+--- gcc-4.6.4-clean/gcc/opth-gen.awk	2011-02-08 10:41:00.000000000 -0700
++++ gcc-4.6.4/gcc/opth-gen.awk	2015-07-20 19:44:52.774843181 -0600
+@@ -121,7 +121,7 @@
+ END {
+ print "/* This file is auto-generated by opth-gen.awk.  */"
+ print ""
+-print "#ifndef OPTIONS_H"
++print "#if !defined(OPTIONS_H) && !defined(IN_LIBGCC2)"
+ print "#define OPTIONS_H"
+ print ""
+ print "#include \"flag-types.h\""
+@@ -432,18 +432,9 @@
+ 
+ for (i = 0; i < n_opts; i++) {
+ 	opt = opt_args("InverseMask", flags[i])
+-	if (opt ~ ",") {
+-		vname = var_name(flags[i])
+-		macro = "OPTION_"
+-		mask = "OPTION_MASK_"
+-		if (vname == "") {
+-			vname = "target_flags"
+-			macro = "TARGET_"
+-			mask = "MASK_"
+-		}
+-		print "#define " macro nth_arg(1, opt) \
+-		      " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
+-	}
++	if (opt ~ ",")
++		print "#define TARGET_" nth_arg(1, opt) \
++		      " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
+ }
+ print ""
+ 
+diff -urN gcc-4.6.4-clean/gcc/tree.h gcc-4.6.4/gcc/tree.h
+--- gcc-4.6.4-clean/gcc/tree.h	2011-10-06 13:57:52.000000000 -0600
++++ gcc-4.6.4/gcc/tree.h	2015-07-20 19:44:52.774843181 -0600
+@@ -3563,6 +3563,8 @@
+   TI_UINTDI_TYPE,
+   TI_UINTTI_TYPE,
+ 
++  TI_UINT8_TYPE,
++  TI_UINT16_TYPE,
+   TI_UINT32_TYPE,
+   TI_UINT64_TYPE,
+ 
+diff -urN gcc-4.6.4-clean/gcc/version.c gcc-4.6.4/gcc/version.c
+--- gcc-4.6.4-clean/gcc/version.c	2009-04-21 13:03:23.000000000 -0600
++++ gcc-4.6.4/gcc/version.c	2015-07-20 19:44:52.774843181 -0600
+@@ -21,16 +21,16 @@
+ 
+ /* This is the location of the online document giving instructions for
+    reporting bugs.  If you distribute a modified version of GCC,
+-   please configure with --with-bugurl pointing to a document giving
+-   instructions for reporting bugs to you, not us.  (You are of course
+-   welcome to forward us bugs reported to you, if you determine that
+-   they are not bugs in your modifications.)  */
++   please change this to refer to a document giving instructions for
++   reporting bugs to you, not us.  (You are of course welcome to
++   forward us bugs reported to you, if you determine that they are
++   not bugs in your modifications.)  */
+ 
+-const char bug_report_url[] = BUGURL;
++const char bug_report_url[] = "<URL:http://lost.l-w.ca/coco/lwtools/>";
+ 
+ /* The complete version string, assembled from several pieces.
+    BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the
+    Makefile.  */
+ 
+-const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION;
++const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION " (gcc6809lw pl6)";
+ const char pkgversion_string[] = PKGVERSION;
+diff -urN gcc-4.6.4-clean/libgcc/config.host gcc-4.6.4/libgcc/config.host
+--- gcc-4.6.4-clean/libgcc/config.host	2011-11-23 15:15:54.000000000 -0700
++++ gcc-4.6.4/libgcc/config.host	2015-07-20 19:44:52.774843181 -0600
+@@ -371,6 +371,8 @@
+  	;;
+ m32rle-*-linux*)
+ 	;;
++m6809*)
++	;;
+ m68hc11-*-*|m6811-*-*)
+         ;;
+ m68hc12-*-*|m6812-*-*)
+diff -urN gcc-4.6.4-clean/libgcc/fixed-obj.mk gcc-4.6.4/libgcc/fixed-obj.mk
+--- gcc-4.6.4-clean/libgcc/fixed-obj.mk	2007-09-17 16:18:13.000000000 -0600
++++ gcc-4.6.4/libgcc/fixed-obj.mk	2015-07-20 19:44:52.774843181 -0600
+@@ -23,7 +23,7 @@
+ #$(info $o$(objext): -DL$($o-label) $($o-opt))
+ 
+ $o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
+-	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
++	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide) -save-temps
+ 
+ ifeq ($(enable_shared),yes)
+ $(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
+diff -urN gcc-4.6.4-clean/libgcc/Makefile.in gcc-4.6.4/libgcc/Makefile.in
+--- gcc-4.6.4-clean/libgcc/Makefile.in	2012-12-04 12:11:33.000000000 -0700
++++ gcc-4.6.4/libgcc/Makefile.in	2015-07-20 19:44:52.774843181 -0600
+@@ -374,8 +374,8 @@
+ # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
+ lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
+ $(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(lib2funcs-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -410,8 +410,9 @@
+ # Build LIB2_DIVMOD_FUNCS.
+ lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
+ $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  -fexceptions -fnon-call-exceptions $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c \
++	  -fexceptions -fnon-call-exceptions $(vis_hide) -save-temps
+ libgcc-objects += $(lib2-divmod-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -443,7 +444,8 @@
+ ifneq ($(FPBIT),)
+ fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
+ $(fpbit-o): %$(objext): $(FPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
++	ln -sf $(FPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(fpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -458,7 +460,8 @@
+ ifneq ($(DPBIT),)
+ dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
+ $(dpbit-o): %$(objext): $(DPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
++	ln -sf $(DPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(dpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+diff -urN gcc-4.6.4-clean/README.LW gcc-4.6.4/README.LW
+--- gcc-4.6.4-clean/README.LW	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/README.LW	2015-07-20 19:44:52.774843181 -0600
+@@ -0,0 +1,14 @@
++This is a port of gcc6809 which is designed to work with the lwtools
++cross-assembler and linker package.  You will need several scripts from that
++package, available at http://lost.l-w.ca/coco/lwtools/, in order to use
++this.  Instructions for building are present in the lwtools package.
++
++This work is based extensively on the gcc6809 4.3.4-3 release by Brian
++Dominy (brian@oddchange.com) with some significant renovations to make it
++work with gcc 4.6.1.
++
++There is no guarantee that it will work for any particular purpose you
++choose to put it to.
++
++If you run into any problems, contact William Astle (lost@l-w.ca). DO NOT
++contact the main GCC developers!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/gcc6809lw-4.6.4-8.patch	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,8148 @@
+diff -urN gcc-4.6.4-clean/config.sub gcc-4.6.4/config.sub
+--- gcc-4.6.4-clean/config.sub	2010-05-25 07:22:07.000000000 -0600
++++ gcc-4.6.4/config.sub	2017-11-28 21:12:11.136911706 -0700
+@@ -313,7 +313,7 @@
+ 	c6x)
+ 		basic_machine=tic6x-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
++	m6809 | m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ 		# Motorola 68HC11/12.
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+@@ -354,7 +354,7 @@
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
+ 	| lm32-* \
+-	| m32c-* | m32r-* | m32rle-* \
++	| m32c-* | m32r-* | m32rle-* | m6809-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ 	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+@@ -509,6 +509,10 @@
+ 		basic_machine=arm-unknown
+ 		os=-cegcc
+ 		;;
++	coco)
++		basic_machine=coco
++		os=-none
++		;;
+ 	convex-c1)
+ 		basic_machine=c1-convex
+ 		os=-bsd
+diff -urN gcc-4.6.4-clean/configure gcc-4.6.4/configure
+--- gcc-4.6.4-clean/configure	2011-12-18 03:03:44.000000000 -0700
++++ gcc-4.6.4/configure	2017-11-28 21:12:11.136911706 -0700
+@@ -3439,6 +3439,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/configure.ac gcc-4.6.4/configure.ac
+--- gcc-4.6.4-clean/configure.ac	2011-11-18 04:45:44.000000000 -0700
++++ gcc-4.6.4/configure.ac	2017-11-28 21:12:11.140911685 -0700
+@@ -885,6 +885,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/gcc/calls.c gcc-4.6.4/gcc/calls.c
+--- gcc-4.6.4-clean/gcc/calls.c	2012-02-09 10:27:25.000000000 -0700
++++ gcc-4.6.4/gcc/calls.c	2017-11-28 21:12:11.140911685 -0700
+@@ -2561,7 +2561,7 @@
+ 	 call sequence.
+ 	 Also do the adjustments before a throwing call, otherwise
+ 	 exception handling can fail; PR 19225. */
+-      if (pending_stack_adjust >= 32
++      if (pending_stack_adjust >= 8
+ 	  || (pending_stack_adjust > 0
+ 	      && (flags & ECF_MAY_BE_ALLOCA))
+ 	  || (pending_stack_adjust > 0
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/crt0.S gcc-4.6.4/gcc/config/m6809/crt0.S
+--- gcc-4.6.4-clean/gcc/config/m6809/crt0.S	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/crt0.S	2017-11-28 21:12:11.152911619 -0700
+@@ -0,0 +1,173 @@
++;;;
++;;; Copyright 2006, 2007, 2008, 2009 by Brian Dominy <brian@oddchange.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/>.
++
++	/* Declare external for main() */
++	.globl _main
++
++
++/* The startup is heavily dependent on the type of machine and
++OS environment that is available at the start point.
++For the most part, the general idea is the same across machines,
++but the implementation is vastly different.  This is managed via
++conditional compiles throughout the startup code for each of the
++supported machines. */
++
++#ifdef TARGET_COCO /* CoCo memory map */
++
++#define COCO_RAMROM_MODE 0xFFDE
++#define COCO_ALLRAM_MODE 0xFFDF
++#define COCO_PAGE1 0xFFD5
++
++/* SAM M1 and M0 adjusts the memory size */
++
++#define BASIC_WARMSTART_FLAG 0x0071
++#define BASIC_START 0xA027
++
++#define __STACK_TOP 0x6800
++
++#else /* Simulator (default) memory map */
++
++#define SIM_EXIT_REG 0xFF01
++
++#define __STACK_TOP 0xFE00
++
++#endif
++
++
++	.area .data
++	.area .ctors
++	.area .dtors
++	.area .bss
++
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __exit : Exit point from the program
++	;;; For simulation, this writes to a special I/O register that
++	;;; the simulator interprets as end-of-program.
++	;;;
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++ 	.globl __exit
++__exit:
++#ifdef TARGET_COCO
++	;; Go back to ROM/RAM mode
++	sta	COCO_RAMROM_MODE
++	clr	BASIC_WARMSTART_FLAG
++	jmp   BASIC_START
++#else
++	tfr	x,d
++	stb	SIM_EXIT_REG
++	bra	__exit
++#endif
++
++
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __start : Entry point to the program
++	;;;
++   ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++	.globl __start
++__start:
++
++#ifdef HAVE_DIRECT
++	;; Initialize the direct page pointer
++	lda	#<s_.direct
++	tfr	a,dp
++#endif
++
++#ifdef TARGET_COCO
++	;; Turn off interrupts
++	orcc #(0x10|0x40)
++	
++	;; Setup All RAM Mode
++	sta COCO_ALLRAM_MODE
++#endif /* TARGET_COCO */
++
++	;; Initialize the stack
++	lds	#__STACK_TOP - 2
++	
++	;; Call any "initializer" functions
++	ldu	#s_.ctors
++__ctors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__ctors_done
++	jsr	,y
++	bra	__ctors_loop
++__ctors_done:
++
++	;; Enable interrupts on the simulator
++#ifndef TARGET_COCO
++	andcc	#~(0x10|0x40)
++#endif
++
++	;; Set up the environment
++
++	;; Set up argc/argv arrays
++
++	;; Call the main function.  The exit code will
++	;; be returned in the X register, unless compiled
++	;; with -mdret, in which case it comes back in D.
++	jsr	_main
++
++	;; Call any finalizer functions
++	ldu	#s_.dtors
++__dtors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__dtors_done
++	jsr	,y
++	bra	__dtors_loop
++__dtors_done:
++
++	;; If main returns, then invoke _exit() to stop the program
++	;; The C library doesn't support -mdret yet, so move the
++	;; argument first.
++#ifdef __DRET__
++	tfr	d,x
++#endif
++	jmp	_exit
++
++
++
++	;;;
++	;;; __crt0_vector : Default handler for interrupts
++	;;;
++	.area	.text
++___crt0_vector:
++	;; The default behavior is to simply ignore all
++	;; non-reset interrupts.
++	rti
++
++
++	;;;
++	;;; vector : The interrupt vector table
++	;;; The linker will ensure that this gets loaded at address 0xFFF0.
++	;;;
++	.area vector
++vectors:
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word ___crt0_vector
++	.word __start
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s gcc-4.6.4/gcc/config/m6809/libgcc1.s
+--- gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/libgcc1.s	2017-11-28 21:12:11.152911619 -0700
+@@ -0,0 +1,511 @@
++/* libgcc routines for m6809
++   Copyright (C) 2006 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 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/>.  */
++
++/* As a special exception, if you link this library with other files,
++   some of which are compiled with GCC, to produce an executable,
++   this library does not by itself cause the resulting executable
++   to be covered by the GNU General Public License.
++   This exception does not however invalidate any other reasons why
++   the executable file might be covered by the GNU General Public License.  */
++
++
++#define SIGFPE jmp _abort
++
++
++	; Shift functions
++	; On input, D is value to be shifted, and X has shift count.
++	; Result is also in D.
++
++#ifdef L_ashlhi3
++	.area .text
++	.globl _ashlhi3
++_ashlhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	aslb
++	rola
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++#ifdef L_ashrhi3
++	.area .text
++	.globl _ashrhi3
++_ashrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	asra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++#ifdef L_lshrhi3
++	.area .text
++	.globl _lshrhi3
++_lshrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	lsra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++
++#ifdef L_softregs
++	.area		direct
++	.globl	m0, m1, m2, m3, m4, m5, m6, m7
++	.globl	m8, m9, m10, m11, m12, m13, m14, m15
++m0: .blkb 1
++m1: .blkb 1
++m2: .blkb 1
++m3: .blkb 1
++m4: .blkb 1
++m5: .blkb 1
++m6: .blkb 1
++m7: .blkb 1
++m8: .blkb 1
++m9: .blkb 1
++m10: .blkb 1
++m11: .blkb 1
++m12: .blkb 1
++m13: .blkb 1
++m14: .blkb 1
++m15: .blkb 1
++#endif
++
++
++#ifdef L_ashlsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashlsi3_one:
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	rts
++#endif
++
++#ifdef L_ashlsi3
++	/* X points to the SImode (source/dest)
++		B is the count */
++_ashlsi3:
++	pshs	u
++	cmpb	#16
++	blt	try8
++	subb	#16
++	; Shift by 16
++	ldu	2,x
++	stu	,x
++try8:
++	cmpb	#8
++	blt	try_rest
++	subb	#8
++	; Shift by 8
++
++try_rest:
++	tstb
++	beq	done
++do_rest:
++	; Shift by 1
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	decb
++	bne	do_rest
++done:
++	puls	u,pc
++#endif
++
++#ifdef L_ashrsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashrsi3_one:
++	asr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_lshrsi3_one
++	.area		.text
++	.globl	_lshrsi3_one
++_lshrsi3_one:
++	lsr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_clzsi2
++	.area .text
++	.globl ___clzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of leading zeros
++	; This function destroys the value in D.
++___clzhi2:
++	pshs	x
++	; Find the offset of the leftmost '1' bit in
++	; the left half of the word.
++	;
++	; Bits are numbered in the table with 1 meaning the
++	; LSB and 8 meaning the MSB.
++	;
++	; If nonzero, then clz is 8-a.
++	tfr	x,d
++	ldx	#___clz_tab
++	tfr	a,b
++	clra
++	ldb	d,x
++	bne	upper_bit_set
++
++lower_bit_set:
++	; If the upper byte is zero, then check the lower
++	; half of the word.  Return 16-a.
++	puls	d
++	clra
++	ldb	d,x
++	negb
++	addb	#16
++	bra	done
++
++upper_bit_set:
++	negb
++	addb	#8
++	puls	x
++
++done:
++	tfr	d,x
++	puls	pc
++#endif
++
++#ifdef L_clzdi2
++	.area .text
++	.globl ___clzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___clzsi2:
++	; Check the upper 16-bit word
++	; If it is not zero, then return clzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	2,s
++	lbne	___clzhi2
++	ldx	4,s
++	jsr	___clzhi2
++	leax	16,x
++	rts
++#endif
++
++#ifdef L_ctzsi2
++	.area .text
++	.globl ___ctzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of trailing zeros
++	; F(x) = 15 - clzhi2(X & -x)
++	; This function destroys the value in D.
++___ctzhi2:
++	tfr	x,d
++	coma
++	comb
++	addd	#1
++	pshs	a
++	pshs	b
++	tfr	x,d
++	andb	,s+
++	anda	,s+
++	tfr	d,x
++	jsr	___clzhi2
++	tfr	x,d
++	subd	#16
++	coma
++	comb
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_ctzdi2
++	.area .text
++	.globl ___ctzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___ctzsi2:
++	; Check the lower 16-bit word
++	; If it is not zero, then return ctzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	4,s
++	lbne	___ctzhi2
++	ldx	2,s
++	jsr	___ctzhi2
++	leax	16,x
++	rts
++#endif
++
++
++#ifdef L_mulhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___mulhi3 - signed/unsigned multiply
++;;; Called by GCC to implement 16x16 multiplication
++;;; Arguments: Two 16-bit values, one in stack, one in X.
++;;; Result: 16-bit result in X
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _mulhi3
++_mulhi3:
++	pshs	x
++	lda   5,s   ; left msb * right lsb * 256
++	ldb   ,s
++	mul
++	tfr   b,a
++	clrb
++	tfr   d,x
++	ldb   1,s   ; left lsb * right msb * 256
++	lda   4,s
++	mul
++	tfr   b,a
++	clrb
++	leax  d,x
++	ldb   1,s   ; left lsb * right lsb
++	lda   5,s
++	mul
++	leax  d,x
++	puls	d,pc  ; kill D to remove initial push
++#endif
++
++
++#ifdef L_divhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___divhi3 - signed division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _divhi3
++_divhi3:
++	ldd	2,s
++	bne	do_div		; check dividend
++	SIGFPE
++do_div:
++	pshs	x
++	jsr	_seuclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_modhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___modhi3 - signed modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _modhi3
++_modhi3:
++	ldd	2,s
++	bne	do_mod		; check dividend
++	SIGFPE
++do_mod:
++	pshs	x
++	jsr	_seuclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++
++#ifdef L_udivhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___udivhi3 - unsigned division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _udivhi3
++_udivhi3:
++	ldd	2,s
++	bne	do_udiv		; check dividend
++	SIGFPE
++do_udiv:
++	pshs	x
++	jsr	_euclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_umodhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___umodhi3 - unsigned modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _umodhi3
++_umodhi3:
++	ldd	2,s
++	bne	do_umod		; check dividend
++	SIGFPE
++do_umod:
++	pshs	x
++	jsr	_euclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_euclid
++;	unsigned euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _euclid
++;	quotient on the stack (left)
++;	modulus in d
++
++	.area	.text
++	.globl	_euclid
++	left=5
++	right=1			; word
++	count=0			; byte
++	CARRY=1			; alias
++_euclid:
++	leas	-3,s		; 2 local variables
++	clr	count,s		; prescale divisor
++	inc	count,s
++	tsta
++presc:
++	bmi	presc_done
++	inc	count,s
++	aslb
++	rola
++	bra	presc
++presc_done:
++	std	right,s
++	ldd	left,s
++	clr	left,s		; quotient = 0
++	clr	left+1,s
++mod1:
++	subd	right,s		; check subtract
++	bcc	mod2
++	addd	right,s
++	andcc	#~CARRY
++	bra	mod3
++mod2:
++	orcc	#CARRY
++mod3:
++	rol	left+1,s	; roll in carry
++	rol	left,s
++	lsr	right,s
++	ror	right+1,s
++	dec	count,s
++	bne	mod1
++	leas	3,s
++	rts
++#endif
++
++#ifdef L_seuclid
++;	signed euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _seuclid
++;	quotient on the stack (left)
++;	modulus in d
++	.area	.text
++	.globl	_seuclid
++	left=6
++	right=2
++	quot_sign=1
++	mod_sign=0
++_seuclid:
++	leas	-4,s		; 3 local variables
++	std	right,s
++	clr	mod_sign,s
++	clr	quot_sign,s
++	ldd	left,s
++	bge	mod_abs
++	inc	mod_sign,s	; sign(mod) = sign(left)
++	inc	quot_sign,s
++	bsr	negd		; abs(left) -> D
++mod_abs:
++	pshs	b,a		; push abs(left)
++	ldd	right+2,s	; all references shifted by 2
++	bge	quot_abs
++	dec	quot_sign+2,s	; sign(quot) = sign(left) XOR sign(right)
++	bsr	negd		; abs(right) -> D
++quot_abs:
++	jsr	_euclid		; call (unsigned) euclidean division
++	std	right+2,s
++	puls	a,b		; quot -> D
++	tst	quot_sign,s	; all references no longer shifted
++	beq	quot_done
++	bsr	negd
++quot_done:
++	std	left,s		; quot -> left
++	ldd	right,s
++	tst	mod_sign,s
++	beq	mod_done
++	bsr	negd
++mod_done:
++	leas	4,s		; destroy stack frame
++	rts
++
++negd:				; self-explanatory !
++	nega
++	negb
++	sbca	#0
++	rts
++#endif
++
++
++
++#ifdef L_pending_addsi3
++_addsi3:
++	rts
++#endif /* L_pending_addsi3 */
++
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.c gcc-4.6.4/gcc/config/m6809/m6809.c
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.c	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.c	2017-11-28 21:12:11.152911619 -0700
+@@ -0,0 +1,3025 @@
++/*-------------------------------------------------------------------
++	FILE: m6809.c
++-------------------------------------------------------------------*/
++/* Subroutines for insn-output.c for MC6809.
++   Copyright (C) 1989-2007 Free Software Foundation, Inc.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ major cleanup, improvements, and upgrade to gcc 3.4 by Brian Dominy
++ (brian@oddchange.com)
++
++ additional adjustments, etc., for gcc 4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++#include <string.h>
++#include <time.h>
++#include <sys/types.h>
++#include <sys/timeb.h>
++#include <stdio.h>
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "tree.h"
++#include "rtl.h"
++#include "tm_p.h"
++#include "regs.h"
++#include "flags.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "tree.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-flags.h"
++#include "output.h"
++#include "insn-attr.h"
++#include "function.h"
++#include "target.h"
++#include "target-def.h"
++#include "expr.h"
++#include "recog.h"
++#include "cpplib.h"
++#include "c-family/c-pragma.h"
++#include "c-family/c-common.h"
++#include "toplev.h"
++#include "optabs.h"
++#include "version.h"
++#include "df.h"
++#include "rtlhooks-def.h"
++
++/* macro to return TRUE if length of operand mode is one byte */
++#define BYTE_MODE(X) ((GET_MODE_SIZE (GET_MODE (X))) == 1)
++
++
++/* REAL_REG_P(x) is a true if the rtx 'x' represents a real CPU
++register and not a fake one that is emulated in software. */
++#define REAL_REG_P(x) (REG_P(x) && !M_REG_P(x))
++
++/*-------------------------------------------------------------------
++    Target hooks, moved from target.h
++-------------------------------------------------------------------*/
++static void m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED);
++
++#undef TARGET_ENCODE_SECTION_INFO
++#define TARGET_ENCODE_SECTION_INFO m6809_encode_section_info
++
++#undef TARGET_ASM_FILE_START
++#define TARGET_ASM_FILE_START m6809_asm_file_start
++
++#undef TARGET_ASM_ALIGNED_HI_OP
++#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_ALIGNED_SI_OP
++#define TARGET_ASM_ALIGNED_SI_OP NULL
++
++#undef TARGET_ASM_UNALIGNED_HI_OP
++#define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_UNALIGNED_SI_OP
++#define TARGET_ASM_UNALIGNED_SI_OP NULL
++
++#undef TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS m6809_rtx_costs
++
++#undef TARGET_ATTRIBUTE_TABLE
++#define TARGET_ATTRIBUTE_TABLE m6809_attribute_table
++
++#undef TARGET_INIT_BUILTINS
++#define TARGET_INIT_BUILTINS m6809_init_builtins
++
++#undef TARGET_EXPAND_BUILTIN
++#define TARGET_EXPAND_BUILTIN m6809_expand_builtin
++
++#undef TARGET_DEFAULT_TARGET_FLAGS
++#define TARGET_DEFAULT_TARGET_FLAGS (MASK_REG_ARGS | MASK_DIRECT)
++
++#undef TARGET_FUNCTION_OK_FOR_SIBCALL
++#define TARGET_FUNCTION_OK_FOR_SIBCALL m6809_function_ok_for_sibcall
++
++#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
++#define TARGET_ASM_TRAMPOLINE_TEMPLATE m6809_asm_trampoline_template
++
++#undef TARGET_TRAMPOLINE_INIT
++#define TARGET_TRAMPOLINE_INIT m6809_initialize_trampoline
++
++#undef TARGET_FRAME_POINTER_REQUIRED
++#define TARGET_FRAME_POINTER_REQUIRED m6809_frame_pointer_required
++
++#undef TARGET_OPTION_OVERRIDE
++#define TARGET_OPTION_OVERRIDE m6809_override_options
++
++/* External variables used */
++extern int reload_completed;   /* set in toplev.c */
++extern FILE *asm_out_file;
++
++static int last_mem_size;   /* operand size (bytes) */
++
++/* True if the section was recently changed and another .area
++ * directive needs to be output before emitting the next label. */
++int section_changed = 0;
++
++/* Section names.  The defaults here are used until an
++ * __attribute__((section)) is seen that changes it. */
++char code_section_op[128] = "\t.area .text";
++char data_section_op[128] = "\t.area .data";
++char bss_section_op[128] = "\t.area .bss";
++const char *code_bank_option = 0;
++
++/* TRUE if the direct mode prefix might be valid in this context.
++ * This is set by 'print_address' prior to calling output_addr_const,
++ * which performs into 'print_direct_prefix' to do the final checks. */
++static int check_direct_prefix_flag;
++
++/* Nonzero if an address is being printed in a context which does not
++ * permit any PIC modifications to the address */
++static int pic_ok_for_addr_p = 1;
++
++/* Current code page.  This supports machines which can do bank
++ * switching to allow for more than 64KB of code/data. */
++char far_code_page[64];
++
++/* Current bank name */
++static char current_bank_name[8] = "-1";
++
++/* Default bank name */
++static char default_code_bank_name[8] = "-1";
++
++/* Direct memory reserved as soft registers */
++unsigned int m6809_soft_regs = 0;
++
++/* ABI version */
++unsigned int m6809_abi_version = M6809_ABI_VERSION_REGS;
++
++
++/**
++ * Called after options have been parsed.
++ * If overrides have been specified on the command-line, then
++ * these values are copied into the main storage variables.
++ */
++void
++m6809_override_options (void)
++{
++	/* Handle -mfar-code-page */
++	if (far_code_page_option == 0)
++		far_code_page_option = "__default_code_page";
++	strcpy (far_code_page, far_code_page_option);
++
++	/* Handle -mcode-section, -mdata-section, and -mbss-section */
++	if (code_section_ptr != 0)
++		sprintf (code_section_op, "\t.area %s", code_section_ptr);
++	if (data_section_ptr != 0)
++		sprintf (data_section_op, "\t.area %s", data_section_ptr);
++	if (bss_section_ptr != 0)
++		sprintf (bss_section_op, "\t.area %s", bss_section_ptr);
++
++	/* Handle -mcode-bank */
++	if (code_bank_option != 0)
++		sprintf (default_code_bank_name, "%s", code_bank_option);
++
++	/* Handle -mabi-version or -mno-reg-args */
++	if (m6809_abi_version_ptr != 0)
++	{
++		if (!strcmp (m6809_abi_version_ptr, "stack"))
++			m6809_abi_version = M6809_ABI_VERSION_STACK;
++		else if (!strcmp (m6809_abi_version_ptr, "regs"))
++			m6809_abi_version = M6809_ABI_VERSION_REGS;
++		else if (!strcmp (m6809_abi_version_ptr, "bx"))
++			m6809_abi_version = M6809_ABI_VERSION_BX;
++		else if (!strcmp (m6809_abi_version_ptr, "latest"))
++			m6809_abi_version = M6809_ABI_VERSION_LATEST;
++		else
++			m6809_abi_version = atoi (m6809_abi_version_ptr);
++	}
++
++	/* The older -mno-reg-args option is deprecated, and treated
++	as -mabi=stack. */
++	if (!TARGET_REG_ARGS)
++   {
++      warning (WARNING_OPT "-mno-reg-args deprecated; use -mabi=stack instead.");
++      m6809_abi_version = M6809_ABI_VERSION_STACK;
++   }
++
++	/* -fexceptions is unsupported */
++	flag_exceptions = 0;
++	flag_non_call_exceptions = 0;
++	flag_unwind_tables = 0;
++}
++
++
++/**
++ * Output prefix that directs the assembler to use a direct-mode
++ * instruction if globally enabled, address is a symbol, and symbol
++ * has been marked as in direct page.  Also, never do this if
++ * using the indirect mode. */
++void
++print_direct_prefix (FILE * file, rtx addr)
++{
++	if (TARGET_DIRECT &&
++       (GET_CODE (addr) == SYMBOL_REF) && 
++       SYMBOL_REF_FLAG (addr) &&
++       check_direct_prefix_flag)
++   {
++      putc ('*', file);
++   }
++}
++
++
++/** Prints an operand (that is not an address) in assembly from RTL. */
++void
++print_operand (FILE * file, rtx x, int code)
++{
++	if (REG_P (x)) {
++		/* gcc currently allocates the entire 16-bit 'd' register
++		 * even when it only needs an 8-bit value.  So here it
++		 * is tricked into printing only the lower 8-bit 'b'
++		 * register into the assembly output.
++		 *
++		 * Eventually gcc should be modified to allocate a/b
++		 * independently and this hack can be removed.
++		 *
++		 * Occasionally, we may want to do an operation using
++		 * the 'a' register instead of 'b'; use the 'A' code
++		 * to specify that.
++		 */
++		if (code == 'A')
++			fputs ("a", file);
++		else if ((BYTE_MODE (x)) && (REGNO (x) == HARD_D_REGNUM))
++			fputs ("b", file);
++		else if (M_REG_P (x) && code == 'L')
++			/* Soft registers can be treated like memory and accessed
++			 * at a particular offset. TODO : handle 'W' */
++			fputs (reg_names[REGNO (x)+1], file);
++		else
++			fputs (reg_names[REGNO (x)], file);
++	}
++
++	else if (MEM_P (x)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (x));
++		if (code == 'L') {	/* LSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 1);
++		}
++		else if (code == 'M') { /* MSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 0);
++		}
++		else if (code == 'W') { /* least significant half of 32-bit */
++			x = adjust_address (x, HImode, 2);
++		}
++
++		pic_ok_for_addr_p = (code != 'C');
++		output_address (XEXP (x, 0));
++	}
++
++	else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) {
++		union { double d; int i[2]; } u;
++		u.i[0] = CONST_DOUBLE_LOW (x);
++		u.i[1] = CONST_DOUBLE_HIGH (x);
++		fprintf (file, "#%#9.9g", u.d);
++	}
++
++	else if (code == 'R') {
++		fprintf (file, "%s", 
++			m6809_get_regs_printable (INTVAL (x)));
++	}
++
++	else {
++		if (code == 'L') {	/* LSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, (INTVAL(x) & 0xff));
++		}
++		else if (code == 'M') {	/* MSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, ((INTVAL(x) >> 8) & 0xff));
++		}
++
++		putc ('#', file);
++		output_addr_const (file, x);
++	}
++}
++
++
++/** Prints an address operand to assembler from its RTL representation. */
++void
++print_operand_address (FILE *file, rtx addr)
++{
++	register rtx base = 0;
++	register rtx offset = 0;
++	int regno;
++	int indirect_flag = 0;
++
++	check_direct_prefix_flag = 0;
++
++	/*** check for indirect addressing ***/
++	if (MEM_P (addr)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (addr));
++		addr = XEXP (addr, 0);
++		if (pic_ok_for_addr_p)
++		{
++			indirect_flag = 1;
++			fprintf (file, "[");
++		}
++	}
++
++
++	switch (GET_CODE (addr)) {
++		case REG:
++			regno = REGNO (addr);
++			fprintf (file, ",%s", reg_names[regno]);
++			break;
++
++		case PRE_DEC:
++			regno = REGNO (XEXP (addr, 0));
++			fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++			fprintf (file, "%s", reg_names[regno]);
++			break;
++
++		case POST_INC:
++			regno = REGNO (XEXP (addr, 0));
++			fprintf (file, ",%s", reg_names[regno]);
++			fputs (((last_mem_size == 1) ? "+" : "++"), file);
++			break;
++
++		case PLUS:
++			base = XEXP (addr, 0);
++			if (MEM_P (base))
++				base = XEXP (base, 0);
++
++			offset = XEXP (addr, 1);
++			if (MEM_P (offset))
++				offset = XEXP (offset, 0);
++
++			if ((CONSTANT_ADDRESS_P (base)) && (CONSTANT_ADDRESS_P (offset))) {
++				if (!indirect_flag)
++					check_direct_prefix_flag = 1;
++				output_addr_const (file, base);
++				check_direct_prefix_flag = 0;
++				fputs ("+", file);
++				output_addr_const (file, offset);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (base)) && (A_REG_P (offset))) {
++				output_addr_const (file, base);
++				fprintf (file, ",%s", reg_names[REGNO (offset)]);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (offset)) && (A_REG_P (base))) {
++				output_addr_const (file, offset);
++				fprintf (file, ",%s", reg_names[REGNO (base)]);
++			}
++
++			/*** accumulator offset ***/
++			else if (((D_REG_P (offset)) || (Q_REG_P (offset)))
++			&& (A_REG_P (base))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (offset)], reg_names[REGNO (base)]);
++			}
++
++			else if (((D_REG_P (base)) || (Q_REG_P (base)))
++			&& (A_REG_P (offset))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (base)], reg_names[REGNO (offset)]);
++			}
++
++			else if (GET_CODE (base) == PRE_DEC) {
++				regno = REGNO (XEXP (base, 0));
++				fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++				fprintf (file, "%s", reg_names[regno]);
++			}
++
++			else
++				abort ();
++
++			break;
++
++   default:
++		/* Set this global before calling output_addr_const() */
++		if (!indirect_flag)
++			check_direct_prefix_flag = 1;
++
++		/* When printing a SYMBOL_REF in PIC mode, do not print the leading
++		 * '#' and follow it by ',pcr' to enable relative addressing. */
++		if (flag_pic && pic_ok_for_addr_p && GET_CODE (addr) == SYMBOL_REF)
++		{
++			ASM_OUTPUT_SYMBOL_REF (file, addr);
++			fputs (",pcr", file);
++			pic_ok_for_addr_p = 1;
++		}
++		else
++		{
++      	output_addr_const (file, addr);
++		}
++
++		check_direct_prefix_flag = 0;
++      break;
++	}
++
++	if (indirect_flag)
++		fprintf (file, "]");
++}
++
++/*-------------------------------------------------------------------
++    Update the CC Status
++---------------------------------------------------------------------
++   Set the cc_status for the results of an insn whose pattern is EXP.
++   We assume that jumps don't affect the condition codes.
++   All else, clobbers the condition codes, by assumption.
++
++   We assume that ALL add, minus, etc. instructions effect the condition
++   codes.
++-------------------------------------------------------------------*/
++void
++notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
++{
++	int src_code;
++	int dst_code;
++
++	/*** recognize SET insn's ***/
++	if (GET_CODE (exp) == SET)
++	{
++		src_code = GET_CODE (SET_SRC (exp));
++		dst_code = GET_CODE (SET_DEST (exp));
++
++		/* Jumps do not alter the cc's.  */
++		if (SET_DEST (exp) == pc_rtx)
++			return;
++
++		/* Moving one register into another register (tfr):
++		Doesn't alter the cc's.  */
++		if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp))))
++			return;
++
++		/* Moving memory into a register (load): Sets cc's. */
++		if (REG_P (SET_DEST (exp)) && src_code == MEM) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Moving register into memory (store): Sets cc's. */
++		if (dst_code == MEM && REG_P (SET_SRC (exp))) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Function calls clobber the cc's.  */
++		else if (GET_CODE (SET_SRC (exp)) == CALL) {
++			CC_STATUS_INIT;
++			return;
++		}
++
++		/* Tests and compares set the cc's in predictable ways.  */
++		else if (SET_DEST (exp) == cc0_rtx)
++		{
++			cc_status.flags = 0;
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			return;
++		}
++
++		else if (A_REG_P (SET_DEST (exp)))
++		{
++			CC_STATUS_INIT;
++			return;
++		}
++
++		else
++		{
++			/* Certain instructions affect the condition codes. */
++			switch (src_code)
++			{
++				case PLUS:
++				case MINUS:
++				case NEG:
++				case ASHIFT:
++					/* These instructions set the condition codes,
++					 * and may modify the V bit. */
++					cc_status.flags |= CC_NO_OVERFLOW;
++					/* FALLTHRU */
++
++				case AND:
++				case IOR:
++				case XOR:
++				case ASHIFTRT:
++				case LSHIFTRT:
++					/* These instructions set the condition codes,
++					 * but cannot overflow (V=0). */
++					cc_status.value1 = SET_SRC (exp);
++					cc_status.value2 = SET_DEST (exp);
++					break;
++
++				default:
++					/* Everything else is clobbered */
++					CC_STATUS_INIT;
++			}
++			return;
++		}
++	} /* SET */
++
++	else if (GET_CODE (exp) == PARALLEL
++		&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
++	{
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
++			return;
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
++		{
++			CC_STATUS_INIT;
++			cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
++			return;
++		}
++	}
++
++	/*** default action if we haven't recognized something
++	and returned earlier ***/
++	CC_STATUS_INIT;
++}
++
++
++/** Returns nonzero if the expression EXP can be implemented using one
++ * of the 6809's single operand instructions. */
++int
++m6809_single_operand_operator (rtx exp)
++{
++	rtx op1;
++	HOST_WIDE_INT val;
++	enum rtx_code code;
++
++	debug_rtx(exp);
++
++	code = GET_CODE (exp);
++
++	/* Unary operators always qualify */
++	switch (code)
++	{
++		case NEG:
++		case NOT:
++			return 1;
++
++		default:
++			break;
++	}
++
++	/* Binary operators can only qualify if the second
++	 * argument is a CONST_INT of certain value. */
++	op1 = XEXP (exp, 1);
++	if (GET_CODE (op1) != CONST_INT)
++		return 0;
++	val = INTVAL (op1);
++	switch (code)
++	{
++		case PLUS:
++		case MINUS:
++			if (val == -1 || val == 1)
++				return 1;
++			break;
++
++		case ASHIFT:
++		case ASHIFTRT:
++		case LSHIFTRT:
++		case ROTATE:
++		case ROTATERT:
++			if (val == 1)
++				return 1;
++			break;
++
++		default:
++			break;
++	}
++
++	return 0;
++}
++
++
++/** Return a bitarray of the hard registers which are used by a function. */
++unsigned int
++m6809_get_live_regs (void)
++{
++	unsigned int regs = 0;
++	int regno;
++
++	if (frame_pointer_needed)
++		regs |= (1 << HARD_FRAME_POINTER_REGNUM);
++
++	for (regno = HARD_X_REGNUM; regno <= HARD_U_REGNUM; regno++)
++		if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
++			regs |= (1 << regno);
++
++	return regs;
++}
++
++
++/** Return a printable version of a list of hard registers, suitable
++ * for use in a PSHx or PULx insn. */
++const char *
++m6809_get_regs_printable (unsigned int regs)
++{
++	static char list[64];
++	char *listp = list;
++	unsigned int regno;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++		if ((regs & (1 << regno)) && !S_REGNO_P (regno))
++			listp += sprintf (listp,
++				(listp == list) ? "%s" : ",%s", reg_names[regno]);
++
++	return list;
++}
++
++
++/** Return the total number of bytes covered by a set of hard registers. */
++unsigned int
++m6809_get_regs_size (unsigned int regs)
++{
++	unsigned int regno;
++	unsigned int size = 0;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++	{
++		/* Only count register in the given register set */
++		if (REGSET_CONTAINS_P (regno, regs))
++		{
++			/* Add 1 or 2 byte, depending on the size of the register.
++			 * Since 'D' may be in both sets, check for WORD_REGSET first. */
++			if (REGSET_CONTAINS_P(regno, WORD_REGSET))
++				size += 2;
++			else if (REGSET_CONTAINS_P(regno, BYTE_REGSET))
++				size++;
++		}
++	}
++	return size;
++}
++
++
++/* Given the target of call instruction in X,
++ * return the tree node that contains the function declaration for
++ * that target.
++ *
++ * If the rtx or the tree do not appear valid for any reason,
++ * then return NULL_TREE.
++ */
++static tree call_target_decl (rtx x)
++{
++   tree decl;
++
++	/* Make sure the target is really a MEM. */
++	if (!x || !MEM_P (x))
++		return NULL_TREE;
++
++	/* Make sure the address is a SYMBOL_REF. */
++	x = XEXP (x, 0);
++	if (!x || (GET_CODE (x) != SYMBOL_REF))
++		return NULL_TREE;
++
++	/* Get the declaration of this symbol */
++	decl = SYMBOL_REF_DECL (x);
++
++	/* Make sure the declaration is really a function. */
++	if (!decl || (TREE_CODE(decl) != FUNCTION_DECL))
++		return NULL_TREE;
++
++   return decl;
++}
++
++
++/** Returns nonzero if a function, whose declaration is in DECL,
++ * was declared to have the attribute given by ATTR_NAME. */
++int
++m6809_function_has_type_attr_p (tree decl, const char *attr_name)
++{
++	tree type;
++
++	type = TREE_TYPE (decl);
++	return lookup_attribute (attr_name, TYPE_ATTRIBUTES (type)) != NULL;
++}
++
++
++
++/** Returns nonzero if the current function was declared to have the
++ * attribute given by ATTR_NAME. */
++int
++m6809_current_function_has_type_attr_p (const char *attr_name)
++{
++	return m6809_function_has_type_attr_p (current_function_decl, attr_name);
++}
++
++
++/** Return nonzero if the current function has no return value. */
++int
++m6809_current_function_is_void (void)
++{
++   return (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
++}
++
++
++/** Get the value of a declaration's 'bank', as set by the 'bank'
++ * attribute.  If no bank was declared, it returns NULL by default. */
++const char *
++m6809_get_decl_bank (tree decl)
++{
++	tree attr;
++
++	/* Lookup the 'bank' attribute.  If it does not exist, then
++	 * return NULL */
++	attr = lookup_attribute ("bank", DECL_ATTRIBUTES (decl));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* Make sure it has a value assigned to it */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "banked function did not declare a bank number");
++		return NULL;
++	}
++
++	/* Return the bank name */
++	attr = TREE_VALUE (attr);
++	return TREE_STRING_POINTER (attr);
++}
++
++
++void
++m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl)
++{
++	/* Check the function declaration for special properties.
++	 *
++	 * If the function was declare with __attribute__((bank)), output
++	 * assembler definitions to force the function to go into the named
++	 * bank.
++	 */
++	const char *bank_name = m6809_get_decl_bank (decl);
++	if (bank_name != NULL)
++	{
++		/* Declare __self_bank as a local assembler value that denotes
++		 * which bank the current function is in.  This is required only
++		 * when the bank actually changes. */
++		if (strcmp (bank_name, current_bank_name))
++		{
++			fprintf (asm_out_file, "__self_bank\t.equ %s\n", bank_name);
++			strcpy (current_bank_name, bank_name);
++		}
++
++		/* Declare a global assembler value that denotes which bank the
++		 * named function is in. */
++		fprintf (asm_out_file, "__%s_bank\t.gblequ %s\n", name, bank_name);
++
++		/* Force the current function into a new area */
++		fprintf (asm_out_file, "\t.bank bank_%s (FSFX=_%s)\n",
++			bank_name, bank_name);
++		fprintf (asm_out_file, "\t.area bank_%s (BANK=bank_%s)\n",
++			bank_name, bank_name);
++	}
++
++	/* Emit the label for the function's name */
++	ASM_OUTPUT_LABEL (asm_out_file, name);
++}
++
++#if 0
++/**
++ * Handle pragmas.  Note that only the last branch pragma seen in the 
++ * source has any affect on code generation.  
++ */
++
++#define BAD_PRAGMA(msgid, arg) \
++	do { warning (WARNING_OPT msgid, arg); return -1; } while (0)
++
++static int
++pragma_parse (const char *name, tree *sect)
++{
++  tree s, x;
++
++  if (pragma_lex (&x) != CPP_OPEN_PAREN)
++    BAD_PRAGMA ("missing '(' after '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&s) != CPP_STRING)
++    BAD_PRAGMA ("missing section name in '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
++    BAD_PRAGMA ("missing ')' for '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_EOF)
++    warning (WARNING_OPT "junk at end of '#pragma %s'", name);
++
++  *sect = s;
++  return 0;
++}
++
++
++/*
++ * Handle #pragma section.
++ * This is deprecated; code should use __attribute__(section("name"))
++ * instead.
++ */
++void pragma_section (cpp_reader *pfile ATTRIBUTE_UNUSED)
++{
++	tree sect;
++
++	if (pragma_parse ("section", &sect))
++		return;
++
++	snprintf (code_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++	snprintf (data_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++
++	/* Mark a flag that sections have changed.  Upon emitting another
++	 * declaration, the new .area directive will be written. */
++	section_changed++;
++}
++#endif
++
++/**
++ * Check a `double' value for validity for a particular machine mode.
++ * Called by the CHECK_FLOAT_VALUE() machine-dependent macro.
++ */
++int
++check_float_value (enum machine_mode mode, double *d, int overflow)
++{
++	if (mode == SFmode) {
++		if (*d > 1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = 1.7014117331926443e+38;
++		}
++		else if (*d < -1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = -1.7014117331926443e+38;
++		}
++		else if ((*d > 0) && (*d < 2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++		else if ((*d < 0) && (*d > -2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++	}
++	return overflow;
++}
++
++
++
++/** Declare that the target supports named output sections. */
++bool m6809_have_named_section = (bool)1;
++
++
++/** Write to the assembler file a directive to place
++ * subsequent objects to a different section in the
++ * object file.  ASxxxx uses the "area" directive for
++ * this purpose.  It does not however support generalized
++ * alignment, and can only place items on an odd/even
++ * boundary. */
++void
++m6809_asm_named_section (
++	const char *name, 
++	unsigned int flags ATTRIBUTE_UNUSED,
++	tree decl)
++{
++	fprintf (asm_out_file, "\t.area\t%s\n", name);
++}
++
++
++enum reg_class
++m6809_preferred_reload_class (rtx x, enum reg_class regclass)
++{
++	/* Check cases based on type code of rtx */
++	switch (GET_CODE(x))
++	{
++		/*
++		 * Observation, 2015-07-19, William Astle
++		 *
++		 * The original comparison for range for 16 bits was wrong, adding 0x80
++		 * instead of 0x8000. Replaced both 8 bit and 16 bit comparisions with
++		 * a more straight forward range comparison - excessive cleverness isn't
++		 * really required here.
++		 */    
++		case CONST_INT:
++		   /* Constants that can fit into 1 byte should be
++			 * loaded into a Q_REGS reg */
++			if ((INTVAL(x) >= -128 && INTVAL(x) <= 127) &&
++//			if (((unsigned) (INTVAL(x) + 0x80) < 0x100) && 
++  				 (regclass > A_REGS))
++      		return Q_REGS;
++
++			/* 16-bit constants should be loaded into A_REGS
++			 * when possible.  gcc may already require A_REGS
++			 * or D_REGS for certain types of instructions.
++			 * This case applies mostly to simple copy operations
++			 * to/from memory when any register will do, but
++			 * it's best to avoid using D register since it is
++			 * needed for other things.
++			 */
++			else if ((INTVAL(x) >= -32768 && INTVAL(x) <= 32767) &&
++//			else if (((unsigned) (INTVAL(x) + 0x80) < 0x10000) &&
++  				 (regclass > A_REGS))
++      		return A_REGS;
++			break;
++
++		case SYMBOL_REF:
++		case LABEL_REF:
++			/* Addresses should always be loaded into A_REGS */
++			if (regclass >= A_REGS)
++				return (A_REGS);
++
++		default:
++			break;
++	}
++
++	/* Check cases based on mode of rtx */
++   if ((GET_MODE(x) == QImode) && (regclass != A_REGS))
++      return Q_REGS;
++
++	/* Default: return whatever class reload suggested */
++   return regclass;
++}
++
++
++/**
++ * Check a new declaration for the "section" attribute.
++ * If it exists, and the target section is "direct", then mark
++ * the declaration (in RTL) to indicate special treatment.
++ * When the variable is referenced later, we test for this flag
++ * and can emit special asm text to force the assembler to use
++ * short instructions.
++ */
++static void
++m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED)
++{
++   tree attr, id;
++   const char *name;
++   const char *decl_name;
++
++   /* We only care about variable declarations, not functions */
++   if (TREE_CODE (decl) != VAR_DECL)
++      return;
++
++	/* For debugging purposes only; grab the decl's name */
++   decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
++
++	/* Give up if the decl doesn't have any RTL */
++   if (!DECL_RTL (decl))
++      return;
++
++	/* See if it has a section attribute */
++   attr = lookup_attribute ("section", DECL_ATTRIBUTES (decl));
++   if (!attr)
++      return;
++
++	/* See if the section attribute has a value */
++   id = TREE_VALUE (TREE_VALUE (attr));
++   if (!id)
++      return;
++   name = TREE_STRING_POINTER (id);
++   if (!name)
++      return;
++
++	/* See if the value is 'direct'.  If so, mark it. */
++   if (!strcmp (name, "direct"))
++      SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
++}
++
++
++/**
++ * Output code to perform a complex shift, for which there is no
++ * direct support in the instruction set.
++ *
++ * shift1 is an instruction pattern for performing a 1-bit modification.
++ * This code wraps that pattern in a loop to perform the shift N times,
++ * where N is given by the address register in operands[2].
++ *
++ * To support 16-bit shifts, shift2 can also be provided: it is
++ * a second instruction to be included in the loop.  8-bit shift
++ * insns will pass NULL here.
++ *
++ * The insn length of shift1/shift2 is assumed to be 1 byte,
++ * which works in all of the cases it is needed so far.
++ */
++static void
++m6809_gen_register_shift (
++		rtx *operands,
++		const char *shift1,
++		const char *shift2 )
++{
++	char beq_pattern[32];
++   char bra_pattern[32];
++
++	int shiftlen = (shift1 && shift2) ? 2 : 1;
++	int cmplen = (REGNO (operands[2]) == HARD_X_REGNUM) ? 3 : 4;
++
++	int beq_offset = 2 + shiftlen + 2;
++	int bra_offset = shiftlen + 2 + cmplen + 2;
++
++	sprintf (beq_pattern, "beq\t.+%d", beq_offset);
++	sprintf (bra_pattern, "bra\t.-%d", bra_offset);
++
++	output_asm_insn ("pshs\t%2", operands);
++	output_asm_insn ("lea%2\t-1,%2", operands);
++   output_asm_insn ("cmp%2\t#-1", operands);
++   output_asm_insn (beq_pattern, operands);
++	if (shift1)
++		output_asm_insn (shift1, operands);
++	if (shift2)
++		output_asm_insn (shift2, operands);
++	output_asm_insn (bra_pattern, operands);
++	output_asm_insn ("puls\t%2", operands);
++}
++
++
++/** Generate RTL for the upper 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_high (rtx r)
++{
++   unsigned char v = (INTVAL (r) >> 8) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL for the lower 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_low (rtx r)
++{
++   unsigned char v = INTVAL (r) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL to allocate/free bytes on the stack.
++ * CODE is given as MINUS when allocating and PLUS when freeing,
++ * to match the semantics of a downward-growing stack.  SIZE
++ * is always given as a positive integer.
++ */
++static rtx
++gen_rtx_stack_adjust (enum rtx_code code, int size)
++{
++	if (size <= 0)
++		return NULL_RTX;
++
++	if (code == MINUS)
++		size = -size;
++
++	return gen_rtx_SET (Pmode, stack_pointer_rtx, 
++		gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++			gen_int_mode (size, HImode)));
++}
++
++
++/** Generate RTL to push/pop a set of registers. */
++rtx
++gen_rtx_register_pushpop (int op, int regs)
++{
++	rtx nregs = gen_int_mode (regs, QImode);
++	
++	if (op == UNSPEC_PUSH_RS)
++		return gen_register_push (nregs);
++	else
++		return gen_register_pop (nregs);
++}
++
++
++/* Given a register set REGS, where the bit positions correspond to
++ * hard register numbers, return another bitmask that represents the
++ * order in which those registers would be pushed/popped.
++ * Registers that are pushed first have higher bit positions.
++ * The pop order is just the reverse bitmask.
++ * These values are the same as the bitmasks actually used in the
++ * machine instructions. */
++static unsigned int
++register_push_order (int regs)
++{
++	unsigned int order = 0;
++
++	if (REGSET_CONTAINS_P (HARD_PC_REGNUM, regs))
++		order |= 0x80;
++	if (REGSET_CONTAINS_P (HARD_U_REGNUM, regs))
++		order |= 0x40;
++	if (REGSET_CONTAINS_P (HARD_Y_REGNUM, regs))
++		order |= 0x20;
++	if (REGSET_CONTAINS_P (HARD_X_REGNUM, regs))
++		order |= 0x10;
++	if (REGSET_CONTAINS_P (HARD_DP_REGNUM, regs))
++		order |= 0x8;
++	if (REGSET_CONTAINS_P (HARD_B_REGNUM, regs))
++		order |= 0x4;
++	if (REGSET_CONTAINS_P (HARD_A_REGNUM, regs))
++		order |= 0x2;
++	if (REGSET_CONTAINS_P (HARD_CC_REGNUM, regs))
++		order |= 0x1;
++
++	if (REGSET_CONTAINS_P (HARD_D_REGNUM, regs))
++		order |= (0x4 | 0x2);
++	return order;
++}
++
++
++/* Returns nonzero if two consecutive push or pop instructions,
++ * as determined by the OP, can be merged into a single instruction.
++ * The first instruction in the sequence pushes/pops REGS1; the
++ * second applies to REGS2.
++ *
++ * If true, the resulting instruction can use (regs1 | regs2)
++ * safely.
++ */
++int
++m6809_can_merge_pushpop_p (int op, int regs1, int regs2)
++{
++	/* Register sets must not overlap */
++	if (regs1 & regs2)
++		return 0;
++
++	if (op == UNSPEC_PUSH_RS)
++		return (register_push_order (regs1) > register_push_order (regs2));
++	else if (op == UNSPEC_POP_RS)
++		return (register_push_order (regs1) < register_push_order (regs2));
++	else
++		return 0;
++}
++
++
++/** Emit instructions for making a library call.
++ * MODE is the mode of the operation.
++ * NAME is the library function name.
++ * OPERANDS is the rtx array provided by the recognizer.
++ * COUNT is the number of input operands to the call, and
++ * should be 1 for a unary op or 2 for a binary op.
++ */
++void
++emit_libcall_insns (enum machine_mode mode, 
++	const char *name, 
++	rtx *operands,
++	int count)
++{
++	/* Generate an rtx for the call target. */
++	rtx symbol = gen_rtx_SYMBOL_REF (Pmode, name);
++
++	/* Emit the library call.  Slightly different based
++	on the number of operands */
++	if (count == 2)
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			2, operands[1], mode, operands[2], mode);
++	else
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			1, operands[1], mode);
++
++	/* The library call is expected to put its result
++	in LIBCALL_VALUE, so need to copy it into the destination. */
++	emit_move_insn (operands[0], LIBCALL_VALUE(mode));
++}
++
++
++/**
++ * A small helper function that writes out a single branch instruction.
++ * OPCODE is the short name, e.g. "ble".
++ * OPERANDS has the rtx for the target label.
++ * LONG_P is nonzero if we are emitting a long branch, and need to
++ * prepend an 'l' to the opcode name.
++ */
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p)
++{
++	char pattern[64];
++	sprintf (pattern, "%s%s\t%%l0", long_p ? "l" : "", opcode);
++	output_asm_insn (pattern, operands);
++}
++
++/**
++ * Output a branch/conditional branch insn of the proper
++ * length.  code identifies the particular branch insn.
++ * operands holds the branch target in operands[0].
++ * length says what the size of this insn should be.
++ * Based on the length, we know whether it should be a
++ * short (8-bit) or long (16-bit) branch.
++ */
++const char *
++output_branch_insn (enum rtx_code code, rtx *operands, int length)
++{
++	int shortform; 
++
++	/* Decide whether or not to use the long or short form.
++	 * Calculate automatically based on insn lengths. */
++   shortform = ((length > 2) ? 0 : 1);
++
++	/* Determine the proper opcode.
++	 * Use the short (2-byte) opcode if the target is within
++	 * reach.  Otherwise, use jmp (3-byte opcode), unless
++	 * compiling with -fpic, in which case we'll need to use
++	 * lbra (4-byte opcode).
++	 */
++	switch (code)
++	{
++		case LABEL_REF: 
++			if (shortform)
++				output_branch_insn1 ("bra", operands, 0);
++			else if (flag_pic)
++				output_branch_insn1 ("bra", operands, 1);
++			else
++				output_branch_insn1 ("jmp", operands, 0);
++			break;
++		case EQ:
++			output_branch_insn1 ("beq", operands, !shortform);
++			break;
++		case NE:
++			output_branch_insn1 ("bne", operands, !shortform);
++			break;
++		case GT:
++			output_branch_insn1 ("bgt", operands, !shortform);
++			break;
++		case GTU:
++			output_branch_insn1 ("bhi", operands, !shortform);
++			break;
++		case LT:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("blt", operands, !shortform);
++			}
++			break;
++		case LTU:
++			output_branch_insn1 ("blo", operands, !shortform);
++			break;
++		case GE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bpl", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("bge", operands, !shortform);
++			}
++			break;
++		case GEU:
++			output_branch_insn1 ("bhs", operands, !shortform);
++			break;
++		case LE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++				output_branch_insn1 ("beq", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("ble", operands, !shortform);
++			}
++			break;
++		case LEU:
++			output_branch_insn1 ("bls", operands, !shortform);
++			break;
++		default:
++			abort();
++			break;
++	}
++	return "";
++}
++
++
++/** Returns the "cost" of an RTL expression.
++ * In general, the expression "COSTS_N_INSNS(1)" is used to represent
++ * the cost of a fast 8-bit arithmetic instruction that operates on
++ * a reg/mem or a reg/immed.  Other costs are relative to this.
++ *
++ * Notes:
++ * - The cost of a REG is always zero; this cannot be changed.
++ *
++ * - On the 6809, instructions on two registers will nearly always take
++ *   longer than those that operate on a register and a constant/memory,
++ *   because of the way the instruction set is structured.
++ *
++ * TODO: multiply HImode by 2 should be done via shifts, instead of add.
++ */
++static bool
++m6809_rtx_costs (rtx X, int code, int outer_code ATTRIBUTE_UNUSED,
++	int *total, bool speed)
++{
++	int has_const_arg = 0;
++	HOST_WIDE_INT const_arg;
++	enum machine_mode mode;
++	int nargs = 1;
++	rtx op0, op1;
++
++	/* Data RTXs return a value between 0-3, depending on complexity.
++	All of these are less than COSTS_N_INSNS(1). */
++	switch (code)
++	{
++		case CC0:
++		case PC:
++			*total = 0;
++			return true;
++
++ 		case CONST_INT:
++    		if (X == const0_rtx)
++			{
++				*total = 0;
++				return true;
++			}
++			else if ((unsigned) INTVAL (X) < 077) 
++			{
++				*total = 1;
++				return true;
++			}
++			else
++			{
++				*total = 2;
++				return true;
++			}
++
++ 		case LABEL_REF: case CONST:
++   		*total = 2;
++			return true;
++
++ 		case SYMBOL_REF:
++			/* References to memory are made cheaper if they have
++			 * the 'direct' mode attribute set */
++			*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++			return true;
++
++		case MEM:
++			/* See what form of address was given */
++			X = XEXP (X, 0);
++			switch (GET_CODE (X))
++			{
++ 				case SYMBOL_REF:
++					*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++					break;
++
++				case CONST_INT:
++					*total = 2;
++					break;
++
++				case MEM:
++					*total = COSTS_N_INSNS (1) + 2;
++					break;
++
++				default:
++					break;
++			}
++			return true;
++
++ 		case CONST_DOUBLE:
++			/* TODO : not sure about this value. */
++   		*total = 3;
++			return true;
++
++		default:
++			break;
++	}
++
++	/* Decode the rtx */
++	mode = GET_MODE (X);
++	op0 = XEXP (X, 0);
++	op1 = XEXP (X, 1);
++
++	/* We don't implement anything in SImode or greater. */
++	if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (SImode))
++	{
++		*total = COSTS_N_INSNS (100);
++		return true;
++	}
++
++	/* Figure out if there is a constant argument, and its value. */
++	if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
++		|| GET_RTX_CLASS (code) == RTX_COMM_ARITH)
++	{
++		nargs = 2;
++		if (GET_CODE (op1) == CONST_INT)
++		{
++			has_const_arg = 1;
++			const_arg = INTVAL (op1);
++		}
++	}
++
++	/* Penalize a reg/reg operation by adding MEMORY_MOVE_COST,
++	 * Ignore soft registers, since these are really in memory.
++	 *
++	 * TODO: penalize HImode reg/reg for most operations, except maybe
++	 * additions since index registers allow for that.
++	 *
++	 * TODO: shifts by constant N do not always require N instructions;
++	 * some of this can be done cheaper.  The number of actual insns can be
++	 * predicted well.
++	 */
++	if (nargs == 2 && REAL_REG_P (op0) && REAL_REG_P (op1))
++	{
++		*total = MEMORY_MOVE_COST (mode, Q_REGS, 0);
++	}
++	else
++	{
++		*total = 0;
++	}
++
++	/* Operator RTXs are counted as COSTS_N_INSNS(N), where N is
++	the estimated number of actual machine instructions needed to
++	perform the computation.  Some small adjustments are made since
++	some "instructions" are more complex than others. */
++	switch (code)
++	{
++		case PLUS: case MINUS: case COMPARE:
++			/* 6809 handles these natively in QImode, and in HImode as long
++			 * as operand 1 is constant. */
++			if (mode == QImode || (mode == HImode && has_const_arg))
++				*total += COSTS_N_INSNS (1);
++			else 
++				*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
++
++			/* -1, 0, and 1 can be done using inherent instructions
++			 * for PLUS and MINUS in QImode, so don't add extra cost. */
++  			if (has_const_arg
++				&& (mode == QImode || mode == HImode)
++				&& (const_arg == -1 || const_arg == 0 || const_arg == 1)
++				&& (code == PLUS || code == MINUS))
++			{
++				return true;
++			}
++			break;
++
++		case AND: case IOR: case XOR:
++		case NEG: case NOT:
++			/* 6809 handles these natively in QImode, but requires
++			 * splitting in HImode.   Treat these as 2 insns. */
++			*total += COSTS_N_INSNS (1) * GET_MODE_SIZE (mode);
++			break;
++
++  		case ASHIFT: case ASHIFTRT: case LSHIFTRT:
++  		case ROTATE: case ROTATERT:
++			/* 6809 can do shift/rotates of a QImode by a constant in
++			 * 1 insn times the shift count, or in HImode by a constant 
++			 * by splitting to 2 insns.
++			 *
++			 * Shift by a nonconstant will take significantly longer
++			 * than any of these. */
++  			if (has_const_arg)
++			{
++				const_arg %= (GET_MODE_SIZE (mode) * 8);
++				if (const_arg == 0)
++				{
++					*total += COSTS_N_INSNS(1);
++					return true;
++				}
++
++				/* HImode shifts greater than 8 get optimized due
++				 * to register transfer from b to a; this cuts down the
++				 * cost. */
++				if (const_arg >= 8)
++				{
++					*total += COSTS_N_INSNS (1);
++					const_arg -= 8;
++				}
++
++				/* The computed cost is 'const_arg' 1-bit shifts, doubled
++				if in HImode, minus the cost of the constant itself which
++				will be added in later but really shouldn't be. */
++				*total += COSTS_N_INSNS (const_arg) * GET_MODE_SIZE (mode) - 1;
++				return true;
++			}
++			else
++			{
++				/* It may take up to 7 iterations of about 6-7 real
++				 * instructions, so make this expensive. */
++				*total += COSTS_N_INSNS (50);
++			}
++  			break;
++
++		case MULT:
++ 		{
++ 			/* Multiply is cheap when both arguments are 8-bits.  They
++ 			could be QImode, or QImode widened to HImode, or a constant
++ 			that fits into 8-bits.  As long as both operands qualify,
++ 			we can use a single mul instruction.
++  
++ 			Assume that fast multiply can be used, and change this if we find
++ 			differently... */
++ 			int ok_for_qihi3 = 1;
++  
++ 			/* Check the first operand */	
++ 			switch (GET_MODE (op0))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++ 					if (GET_CODE (op0) != SIGN_EXTEND && GET_CODE (op0) != ZERO_EXTEND)
++  						ok_for_qihi3 = 0;
++ 					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++  			}
++ 
++			/* Likewise, check the second operand.  This is where constants may appear. */
++ 			switch (GET_MODE (op1))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++					if (GET_CODE (op1) != SIGN_EXTEND && GET_CODE (op1) != ZERO_EXTEND)
++ 						ok_for_qihi3 = 0;
++ 					break;
++ 				case VOIDmode:
++					if (!CONST_OK_FOR_LETTER_P (const_arg, 'K'))
++ 						ok_for_qihi3 = 0;
++					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++ 			}
++ 
++ 			/* Fast multiply takes about 4 times as many cycles as a normal
++ 			arithmetic operation.  Otherwise, it will take an expensive libcall. */
++ 			if (ok_for_qihi3)
++ 				*total += COSTS_N_INSNS (4);
++ 			else
++ 				*total = COSTS_N_INSNS (50);
++  	  		break;
++ 		}
++
++		case DIV: case UDIV: case MOD: case UMOD:
++			/* These all require more expensive libcalls. */
++			*total += COSTS_N_INSNS (100);
++  			break;
++
++		/* TODO : TRUNCATE, SIGN_EXTEND, and ZERO_EXTEND */
++
++		/* These can normally be done with autoincrement, etc., so
++		 * don't charge for them. */
++		case PRE_DEC:
++		case PRE_INC:
++		case POST_DEC:
++		case POST_INC:
++			break;
++
++		default:
++			break;
++	}
++
++	/* Always return false, and let the caller gather the costs
++	 * of the operands */
++	return false;
++}
++
++
++static tree
++m6809_handle_fntype_attribute (tree *node, tree name,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs)
++{
++	if (TREE_CODE (*node) != FUNCTION_TYPE)
++	{
++		warning (WARNING_OPT "'%s' only valid for functions", 
++			IDENTIFIER_POINTER (name));
++		*no_add_attrs = TRUE;
++	}
++
++	return NULL_TREE;
++}
++
++
++static tree
++m6809_handle_data_type_attribute (tree *node ATTRIBUTE_UNUSED,
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED)
++{
++	return NULL_TREE;
++}
++
++
++
++static tree
++m6809_handle_default_attribute (tree *node ATTRIBUTE_UNUSED, 
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED )
++{
++	return NULL_TREE;
++}
++
++
++/* Table of valid machine attributes */
++const struct attribute_spec m6809_attribute_table[] = { /*
++{ name,        min, max, decl,  type, fntype, handler } */
++{ "interrupt", 0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "naked",     0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "far",       0,   1,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "bank",      0,   1,   true,  false, false, m6809_handle_default_attribute },
++{ "boolean",   0,   0,   false, true,  false, m6809_handle_data_type_attribute },
++{ NULL,        0,   0,   false, true,  false, NULL },
++};
++
++
++/** Initialize builtin routines for the 6809. */
++void
++m6809_init_builtins (void)
++{
++	/* Create type trees for each function signature required.
++	 *
++	 * void_ftype_void = void f(void)
++	 * void_ftype_uchar = void f(unsigned char)
++	 * uchar_ftype_uchar2 = unsigned char f (unsigned char, unsigned char)
++	 */
++	tree void_ftype_void = 
++		build_function_type (void_type_node, void_list_node);
++
++	tree void_ftype_uchar =
++		build_function_type (void_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node));
++
++	tree uchar_ftype_uchar2 =
++		build_function_type (unsigned_char_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, 
++				tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node)));
++
++	/* Register each builtin function. */
++	add_builtin_function ("__builtin_swi", void_ftype_void,
++		M6809_SWI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi2", void_ftype_void,
++		M6809_SWI2, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi3", void_ftype_void,
++		M6809_SWI3, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_cwai", void_ftype_uchar,
++		M6809_CWAI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sync", void_ftype_void,
++		M6809_SYNC, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_nop", void_ftype_void,
++		M6809_NOP, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_blockage", void_ftype_void,
++		M6809_BLOCKAGE, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_decimal", uchar_ftype_uchar2,
++		M6809_ADD_DECIMAL, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_carry", uchar_ftype_uchar2,
++		M6809_ADD_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sub_carry", uchar_ftype_uchar2,
++		M6809_SUB_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++}
++
++
++/** Used by m6809_expand_builtin, given a tree ARGLIST which
++ * refers to the operands of a builtin call, return an rtx
++ * that represents the nth operand, as denoted by OPNUM, which
++ * is a zero-based integer.  MODE gives the expected mode
++ * of the operand.
++ *
++ * This rtx is suitable for use in the emitted RTL for the
++ * builtin instruction. */
++rtx
++m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum)
++{
++	tree arg;
++	rtx r;
++
++	arg = CALL_EXPR_ARG (arglist, opnum);
++
++	/* Convert the tree to RTL */
++	r = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
++	if (r == NULL_RTX)
++		return NULL_RTX;
++	return r;
++}
++
++
++/** Expand a builtin that was registered in init_builtins into
++ * RTL.  */
++rtx
++m6809_expand_builtin (tree exp, 
++	rtx target, 
++	rtx subtarget ATTRIBUTE_UNUSED,
++	enum machine_mode mode ATTRIBUTE_UNUSED,
++	int ignore ATTRIBUTE_UNUSED )
++{
++   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
++	tree arglist = exp;
++	unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
++	rtx r0, r1;
++
++	switch (fcode)
++	{
++		case M6809_SWI:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 1);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI2:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 2);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI3:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 3);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_CWAI:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			emit_insn (target = gen_m6809_cwai (r0));
++			return target;
++
++		case M6809_SYNC:
++			emit_insn (target = gen_m6809_sync ());
++			return target;
++
++		case M6809_ADD_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_SUB_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_subqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_NOP:
++			emit_insn (target = gen_nop ());
++			return target;
++
++		case M6809_BLOCKAGE:
++			emit_insn (target = gen_blockage ());
++			return target;
++
++		case M6809_ADD_DECIMAL:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_decimal (target, r0, r1));
++			return target;
++
++		default:
++			warning (WARNING_OPT "unknown builtin expansion ignored");
++			return NULL_RTX;
++	}
++}
++
++
++
++/* Returns nonzero if 'x' represents a function that was declared
++ * as __noreturn__. */
++int
++noreturn_functionp (rtx x)
++{
++	tree decl = call_target_decl (x);
++
++	if (decl == NULL_TREE)
++		return 0;
++	else
++		return TREE_THIS_VOLATILE (decl);
++}
++
++
++const char *
++far_function_type_p (tree type)
++{
++	tree attr;
++	const char *page;
++
++	/* Return whether or not this decl has the far attribute */
++	attr = lookup_attribute ("far", TYPE_ATTRIBUTES (type));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* If it is far, check for a value */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "far code page not specified, using local value");
++		return far_code_page;
++	}
++
++	/* We have a TREE_LIST of attribute values, get the first one.
++	 * It should be an INTEGER_CST. */
++	attr = TREE_VALUE (attr);
++	page = TREE_STRING_POINTER (attr);
++	return page;
++}
++
++
++/* For a far function, returns the identifier that states which page
++ * it resides in.  Otherwise, returns NULL for ordinary functions. */
++const char *
++far_functionp (rtx x)
++{
++	tree decl, decl_type;
++	const char *page;
++
++	/* Find the FUNCTION_DECL corresponding to the rtx being called. */
++	decl = call_target_decl (x);
++	if (decl == NULL_TREE)
++		return NULL;
++
++	/* See if the function has the new 'banked' attribute.  These
++	 * are numeric instead of text */
++	page = m6809_get_decl_bank (decl);
++	if (page)
++		return page;
++
++	/* No, lookup the type of the function and see if the type
++	 * specifies far or not. */
++	decl_type = TREE_TYPE (decl);
++	if (decl_type == NULL_TREE)
++		return NULL;
++	return far_function_type_p (decl_type);
++}
++
++
++
++/** Outputs the assembly language for a far call. */
++void
++output_far_call_insn (rtx *operands, int has_return)
++{
++	static char page_data[64];
++	const char *called_page;
++
++  /* The logic is the same for functions whether or not there
++	* is a return value.  Skip over the return value in this
++	* case, so that the call location is always operands[0].  */
++  if (has_return)
++	  operands++;
++
++  /* Get the name of the page being called */
++  called_page = far_functionp (operands[0]);
++
++#if 0 /* TODO : broken logic */
++  /* See if the called page name is a 'bank' */
++  if (isdigit (*called_page))
++  {
++    /* New style banking */
++	 if (!strcmp (called_page, current_bank_name))
++	 {
++	 	/* Same page */
++  	  	output_asm_insn ("jsr\t%0", operands);
++	 }
++	 else
++	 {
++	 	/* Different page */
++		output_asm_insn ("jsr\t__far_call_handler\t;new style", operands);
++  	  	output_asm_insn ("\t.dw\t%0", operands);
++		sprintf (page_data, "\t.db\t%s", called_page);
++	 	output_asm_insn (page_data, operands);
++	 }
++	 return;
++  }
++#endif
++
++  /* Are we calling a different page than we are running in? */
++  if (!strcmp (called_page, far_code_page))
++  {
++    /* Same page : no need to execute a far call */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t%C0", operands);
++		else
++			output_asm_insn ("jsr\t%0", operands);
++  }
++  else
++  {
++    /* Different page : need to emit far call thunk */
++
++    /* First output a call to the thunk for making far calls. */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t__far_call_handler", operands);
++		else
++			output_asm_insn ("jsr\t__far_call_handler\t;old style", operands);
++  
++    /* Now output the name of the call site */
++    output_asm_insn ("\t.dw\t%C0", operands);
++  
++    /* Finally output the page number */
++    sprintf (page_data, "\t.db\t%s", far_functionp (operands[0]));
++    output_asm_insn (page_data, operands);
++  }
++}
++
++
++int
++m6809_init_cumulative_args (CUMULATIVE_ARGS cum ATTRIBUTE_UNUSED,
++     tree fntype,
++     rtx libname ATTRIBUTE_UNUSED)
++{
++	cum = 0;
++
++	/* For far functions, the current implementation does not allow for
++	 * stack parameters.  So note whenever the called function is far
++	 * and in a different page than the current one; such a function
++	 * should give an error if a stack parameter is generated. */
++	if (fntype)
++	{
++		const char *called_page = far_function_type_p (fntype);
++		if (called_page && strcmp (called_page, far_code_page) && !TARGET_FAR_STACK_PARAM)
++			cum |= CUM_STACK_INVALID;
++	}
++
++	if (fntype && TYPE_ARG_TYPES (fntype) != 0 &&
++		(TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
++	{
++		/* has variable arguments, cannot use registers */
++		cum |= (CUM_X_MASK | CUM_B_MASK | CUM_STACK_ONLY);
++	}
++
++	if (m6809_abi_version == M6809_ABI_VERSION_STACK)
++	{
++		/* cannot use registers ; only use the stack */
++		cum |= (CUM_STACK_ONLY | CUM_X_MASK | CUM_B_MASK);
++	}
++
++	return cum;
++}
++
++
++rtx
++m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump)
++{
++	if (*cump & CUM_STACK_INVALID)
++	{
++		*cump &= ~CUM_STACK_INVALID;
++		error ("far function needs stack, will not work");
++	}
++	return NULL_RTX;
++}
++
++void m6809_asm_trampoline_template(FILE *f)
++{
++	fprintf(f, "ldy #0000\n");
++	fprintf(f, "jmp 0x0000\n");
++}
++
++/*
++ * Trampoline output:
++ *
++ * ldu #&cxt      4 bytes   --LDY- ?? ??
++ * jmp fnaddr     3 bytes   JMP ?? ??
++ */
++void
++m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
++{
++	rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
++	/* TODO - optimize by generating the entire trampoline code here,
++	 * and removing the template altogether, since there are only two
++	 * bytes there that matter. */
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 5)), fnaddr);
++}
++
++
++/** Echo the version of the compiler and the name of the source file
++ * at the beginning of each assembler output file.  asm_out_file
++ * is a global FILE * pointing to the output stream. */
++void
++m6809_asm_file_start (void)
++{
++	const char *module_name;
++
++	fprintf (asm_out_file, "\n;;; gcc for m6809 : %s %s\n",
++		__DATE__, __TIME__);
++	fprintf (asm_out_file, ";;; %s\n", version_string);
++
++	fprintf (asm_out_file, ";;; ABI version %d\n", m6809_abi_version);
++	fprintf (asm_out_file, ";;; %s\n",
++		(TARGET_BYTE_INT ? "-mint8" : "-mint16"));
++	if (TARGET_EXPERIMENT)
++		fprintf (asm_out_file, ";;; -mexperiment\n");
++	if (TARGET_WPC)
++		fprintf (asm_out_file, ";;; -mwpc\n");
++	if (TARGET_6309)
++		fprintf (asm_out_file, ";;; -m6309\n");
++
++	/* Print the name of the module, which is taken as the base name
++	 * of the input file.
++	 * See the 'User-Defined Symbols' section of the assembler
++	 * documentation for the rules on valid symbols.
++	 */
++	module_name = lbasename (main_input_filename);
++
++	fprintf (asm_out_file, "\t.module\t");
++
++	if (*module_name >= '0' && *module_name <= '9')
++		fprintf (asm_out_file, "_");
++
++	while (*module_name)
++	{
++		if ((*module_name >= '0' && *module_name <= '9')
++			|| (*module_name >= 'A' && *module_name <= 'Z')
++			|| (*module_name >= 'a' && *module_name <= 'z')
++			|| *module_name == '$'
++			|| *module_name == '.'
++			|| *module_name == '_')
++		{
++			fprintf (asm_out_file, "%c", *module_name);
++		}
++		else
++		{
++			fprintf (asm_out_file, "_");
++		}
++		module_name++;
++	}
++
++	fprintf (asm_out_file, "\n");
++}
++
++
++/** Returns true if prologue/epilogue code is required for the
++ * current function being compiled.
++ *
++ * This is just the inverse of whether the function is declared as
++ * 'naked'.
++ */
++int
++prologue_epilogue_required (void)
++{
++	return !m6809_current_function_has_type_attr_p ("naked")
++		&& !m6809_current_function_has_type_attr_p ("noreturn");
++}
++
++
++/** Expand RTL for function entry */
++void
++emit_prologue_insns (void)
++{
++  rtx insn;
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  /* Save all registers used, including the frame pointer */
++  if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++  {
++    insn = emit_insn (
++      gen_rtx_register_pushpop (UNSPEC_PUSH_RS, live_regs));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Allocate space for local variables */
++  if (frame_size != 0)
++  {
++    insn = emit_insn (gen_rtx_stack_adjust (MINUS, frame_size));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Set the frame pointer if it is needed */
++  if (frame_pointer_needed)
++  {
++    insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++}
++
++
++/** Expand RTL for function exit */
++void
++emit_epilogue_insns (bool sibcall_p)
++{
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  if (frame_size != 0)
++    emit_insn (gen_rtx_stack_adjust (PLUS, frame_size));
++
++  if (sibcall_p)
++  {
++    if (live_regs)
++      emit_insn (gen_rtx_register_pushpop (UNSPEC_POP_RS, live_regs));
++  }
++  else
++  {
++    if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++        emit_insn (
++          gen_rtx_register_pushpop (UNSPEC_POP_RS, PC_REGBIT | live_regs));
++  
++    if (m6809_current_function_has_type_attr_p ("interrupt"))
++      emit_jump_insn (gen_return_rti ());
++    else
++      emit_jump_insn (gen_return_rts ());
++  }
++}
++
++#if 0
++/** Predefine some preprocessor names according to the currently
++ * selected compiler options */
++void
++m6809_cpu_cpp_builtins (void)
++{
++	if (TARGET_6309)
++	{
++		builtin_define_std ("__M6309__");
++		builtin_define_std ("__m6309__");
++	}
++	else
++	{
++		builtin_define_std ("__M6809__");
++		builtin_define_std ("__m6809__");
++	}
++
++	if (TARGET_BYTE_INT)
++		builtin_define_std ("__int8__");
++	else
++		builtin_define_std ("__int16__");
++
++	switch (m6809_abi_version)
++	{
++		case M6809_ABI_VERSION_STACK:
++			builtin_define_std ("__regargs__");
++			builtin_define_std ("__ABI_STACK__");
++			break;
++		case M6809_ABI_VERSION_REGS:
++			builtin_define_std ("__ABI_REGS__");
++			break;
++		case M6809_ABI_VERSION_BX:
++			builtin_define_std ("__ABI_BX__");
++			break;
++		default:
++			break;
++	}
++
++	if (TARGET_WPC)
++		builtin_define_std ("__WPC__");
++
++	if (TARGET_DRET)
++		builtin_define_std ("__DRET__");
++}
++#endif
++
++#define MAX_ASM_ASCII_STRING 48
++
++void
++m6809_output_ascii (FILE *fp, const char *str, unsigned long size)
++{
++	unsigned long i;
++	bool use_ascii = true;
++
++	/* If the size is too large, then break this up into multiple
++	outputs.  The assembler can only output roughly 48 bytes at a
++	time.  Note that if there are lots of escape sequences in
++	the string, this may fail. */
++	if (size > MAX_ASM_ASCII_STRING)
++	{
++		m6809_output_ascii (fp, str, MAX_ASM_ASCII_STRING);
++		m6809_output_ascii (fp, str + MAX_ASM_ASCII_STRING, 
++			size - MAX_ASM_ASCII_STRING);
++		return;
++	}
++
++	/* Check for 8-bit codes, which cannot be embedded in an .ascii */
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++		if (c >= 0x80)
++		{
++			use_ascii = false;
++			break;
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\t.ascii \"");
++
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++
++		if (use_ascii)
++		{
++		/* Just output the plain character if it is printable,
++		otherwise output the escape code for the character.
++		The assembler recognizes the same C-style octal escape sequences,
++		except that it only supports 7-bit codes. */
++		if (c >= ' ' && c < 0177 && c != '\\' && c != '"')
++  			putc (c, fp);
++		else switch (c) 
++		{
++			case '\n':
++#ifndef TARGET_COCO
++				fputs ("\\n", fp);
++				break;
++#endif
++				/* On the CoCo, we fallthrough and treat '\n' like '\r'. */
++			case '\r':
++				fputs ("\\r", fp);
++				break;
++			case '\t':
++				fputs ("\\t", fp);
++				break;
++			case '\f':
++				fputs ("\\f", fp);
++				break;
++			case 0:
++				fputs ("\\0", fp);
++				break;
++			default:
++				fprintf (fp, "\\%03o", c);
++				break;
++		}
++		}
++		else
++		{
++			fprintf (fp, "\t.byte\t0x%02X\n", c);
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\"\n");
++}
++
++
++void
++m6809_output_quoted_string (FILE *asm_file, const char *string)
++{
++	char c;
++
++	if (strlen (string) > MAX_ASM_ASCII_STRING)
++	{
++		/* The string length is too large.  We'll have to truncate it.
++		This is only called from debugging functions, so it's usually
++		not critical. */
++
++		char truncated_string[MAX_ASM_ASCII_STRING+1];
++
++		/* Copy as many characters as we can. */
++		strncpy (truncated_string, string, MAX_ASM_ASCII_STRING);
++		truncated_string[MAX_ASM_ASCII_STRING] = '\0';
++		string = truncated_string;
++	}
++
++	/* Copied from toplev.c */
++
++	putc ('\"', asm_file);
++	while ((c = *string++) != 0) {
++		if (ISPRINT (c)) {
++			if (c == '\"' || c == '\\')
++				putc ('\\', asm_file);
++			putc (c, asm_file);
++		}
++      else
++			fprintf (asm_file, "\\%03o", (unsigned char) c);
++	}
++	putc ('\"', asm_file);
++}
++
++
++/** Output the assembly code for a shift instruction where the
++ * shift count is not constant. */
++void
++m6809_output_shift_insn (int rtx_code, rtx *operands)
++{
++	struct shift_opcode *op;
++
++	if (GET_CODE (operands[2]) == CONST_INT)
++		abort ();
++
++	if (optimize_size && GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("jsr\t_ashlhi3", operands);
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("jsr\t_ashrhi3", operands);
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("jsr\t_lshrhi3", operands);
++				break;
++		}
++	}
++	else if (GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", "rola");
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asra", "rorb");
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsra", "rorb");
++				break;
++		}
++	}
++	else
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", NULL);
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asrb", NULL);
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsrb", NULL);
++				break;
++		}
++	}
++}
++
++
++void
++m6809_emit_move_insn (rtx dst, rtx src)
++{
++	emit_insn (gen_rtx_SET (VOIDmode, dst, src));
++	if (ACC_A_REG_P (dst))
++		emit_insn (gen_rtx_USE (VOIDmode, dst));
++}
++
++
++/** Split a complex shift instruction into multiple CPU
++ * shift instructions. */
++void
++m6809_split_shift (enum rtx_code code, rtx *operands)
++{
++	enum machine_mode mode;
++	int count;
++
++	mode = GET_MODE (operands[0]);
++	count = INTVAL (operands[2]);
++	
++	/* Handle a shift count outside the range of 0 .. N-1, where
++	 * N is the mode size in bits.  We normalize the count, and
++	 * for negative counts we also invert the direction of the
++	 * shift. */
++	if ((count < 0) || (count >= 8 * GET_MODE_SIZE (mode)))
++	{
++		if (count < 0)
++		{
++			count = -count;
++			code = (code == ASHIFT) ? ASHIFTRT : ASHIFT;
++		}
++		count %= (8 * GET_MODE_SIZE (mode));
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, count)));
++	}
++
++	/* Handle shift by zero explicitly as a no-op. */
++	if (count == 0)
++	{
++		emit_insn (gen_nop ());
++		return;
++	}
++
++	/* Decompose the shift by a constant N > 8 into two
++	 * shifts, first by 8 and then by N-8.
++	 * This "speeds up" the process for large shifts that would be
++	 * handled below, but allows for some optimization.
++	 * In some cases shift by 8 can be implemented fast.  If an
++	 * instruction to shift by 8 is defined, it will be used here;
++	 * otherwise it will be further decomposed as below. */
++	if (mode == HImode && count > 8)
++	{
++		rtx output = operands[0];
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, 8)));
++
++		/* Unsigned shifts always produce a zero in either the
++		 * upper or lower half of the output; then, that part
++		 * does not need to be shifted anymore.  We modify the
++		 * output and the subsequent instructions to operate in
++		 * QImode only on the relevant part. */
++		if (REG_P (output))
++		{
++			if (code == ASHIFT)
++			{
++				output = gen_rtx_REG (QImode, HARD_A_REGNUM);
++				mode = QImode;
++			}
++			else
++			{
++				output = gen_rtx_REG (QImode, HARD_D_REGNUM);
++				mode = QImode;
++			}
++		}
++
++		m6809_emit_move_insn (output,
++			gen_rtx_fmt_ee (code, mode, copy_rtx (output), 
++				gen_rtx_CONST_INT (VOIDmode, count-8)));
++		return;
++	}
++
++	/* Rewrite the unsigned shift of an 8-bit register by a large constant N
++	 * (near to the maximum of 8) as a rotate and mask. */
++	if (mode == QImode && REG_P (operands[0]) && count >= ((code == ASHIFTRT) ? 7 : 6))
++	{
++		unsigned int mask;
++		unsigned int was_signed = (code == ASHIFTRT);
++
++		code = (code == ASHIFT) ? ROTATERT : ROTATE;
++		if (code == ROTATE)
++			mask = (count == 6) ? 0x03 : 0x01;
++		else
++			mask = (count == 6) ? 0xC0 - 0x100 : 0x80 - 0x100;
++		count = 9 - count;
++
++		do {
++			m6809_emit_move_insn (operands[0],
++				gen_rtx_fmt_ee (code, QImode, operands[1], const1_rtx));
++		} while (--count != 0);
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (AND, QImode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, mask)));
++
++		if (was_signed)
++		{
++			emit_insn (gen_negqi2 (operands[0], copy_rtx (operands[0])));
++			if (ACC_A_REG_P (operands[0]))
++				emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
++		}
++		return;
++	}
++
++	/* Decompose the shift by any constant N > 1 into a sequence
++	 * of N shifts.
++	 * This is done recursively, by creating a shift by 1 and a
++	 * shift by N-1, as long as N>1. */
++	if (count > 1)
++	{
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], const1_rtx));
++	
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], 
++				gen_rtx_CONST_INT (VOIDmode, count-1)));
++		return;
++	}
++	
++	/* Decompose the single shift of a 16-bit quantity into two
++	 * CPU instructions, one for each 8-bit half.
++	 */
++	if (mode == HImode && count == 1)
++	{
++		rtx first, second;
++		enum rtx_code rotate_code;
++
++		rotate_code = (code == ASHIFT) ? ROTATE : ROTATERT;
++
++		/* Split the operand into two 8-bit entities.
++		 * FIRST is the one that will get shifted via a regular CPU
++		 * instruction.
++		 * SECOND is the one that will have the result of the first shift
++		 * rotated in.
++		 *
++		 * We initialize first and second as if we are doing a left shift,
++		 * then swap the operands if it's a right shift.
++		 */
++		if (REG_P (operands[0]))
++		{
++			first = gen_rtx_REG (QImode, HARD_D_REGNUM); /* HARD_B_REGNUM? */
++			second = gen_rtx_REG (QImode, HARD_A_REGNUM);
++		}
++		else
++		{
++			first = adjust_address (operands[0], QImode, 1);
++			second = adjust_address (operands[0], QImode, 0);
++		}
++
++		if (rotate_code == ROTATERT)
++		{
++			rtx tmp; tmp = first; first = second; second = tmp;
++		}
++
++		/* Decompose into a shift and a rotate instruction. */
++		m6809_emit_move_insn (first,
++			gen_rtx_fmt_ee (code, QImode, copy_rtx (first), const1_rtx));
++		m6809_emit_move_insn (second,
++			gen_rtx_fmt_ee (rotate_code, QImode, copy_rtx (second), const1_rtx));
++		return;
++	}
++}
++
++
++/** Adjust register usage based on compile-time flags. */
++void
++m6809_conditional_register_usage (void)
++{
++	unsigned int soft_regno;
++
++#ifdef CONFIG_SOFT_REGS_ALWAYS
++	m6809_soft_regs = CONFIG_SOFT_REGS_ALWAYS;
++#else
++	if (!m6809_soft_reg_count)
++		return;
++	m6809_soft_regs = atoi (m6809_soft_reg_count);
++#endif
++
++	if (m6809_soft_regs == 0)
++		return;
++
++	if (m6809_soft_regs > NUM_M_REGS)
++		m6809_soft_regs = NUM_M_REGS;
++
++	/* Registers are marked FIXED by default.  Free up if
++	the user wishes. */
++	for (soft_regno = 1; soft_regno < m6809_soft_regs; soft_regno++)
++	{
++		fixed_regs[SOFT_M0_REGNUM + soft_regno] = 0;
++
++		/* Mark the softregs as call-clobbered, so that they need
++		 * not be saved/restored on function entry/exit. */
++		call_used_regs[SOFT_M0_REGNUM + soft_regno] = 1;
++	}
++}
++
++
++/** Return a RTX representing how to return a value from a function.
++  VALTYPE gives the type of the value, FUNC identifies the function
++  itself.
++
++  In general, we only care about the width of the result. */
++rtx
++m6809_function_value (const tree valtype, const tree func ATTRIBUTE_UNUSED)
++{
++   unsigned int regno;
++	enum machine_mode mode;
++
++	/* Get the mode (i.e. width) of the result. */
++	mode = TYPE_MODE (valtype);
++
++	if (lookup_attribute ("boolean", TYPE_ATTRIBUTES (valtype)))
++      regno = HARD_Z_REGNUM;
++   else if (mode == QImode || (TARGET_DRET && mode == HImode))
++      regno = HARD_D_REGNUM;
++   else
++      regno = HARD_X_REGNUM;
++   return gen_rtx_REG (mode, regno);
++}
++
++
++/** Return 1 if REGNO is possibly needed to return the result
++of a function, 0 otherwise. */
++int
++m6809_function_value_regno_p (unsigned int regno)
++{
++	if (regno == HARD_Z_REGNUM)
++		return 1;
++	else if ((TARGET_BYTE_INT || TARGET_DRET) && regno == HARD_D_REGNUM)
++		return 1;
++	else if (!TARGET_DRET && regno == HARD_X_REGNUM)
++		return 1;
++	else
++		return 0;
++}
++
++
++#ifdef TRACE_PEEPHOLE
++int
++m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage)
++{
++	if (stage == PEEP_END)
++	{
++		printf ("%s: peephole %d pattern and predicate matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	else if (stage == PEEP_COND)
++	{
++		printf ("%s: peephole %d? at least pattern matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	return 1;
++}
++#else
++int
++m6809_match_peephole2 (unsigned int peephole_id ATTRIBUTE_UNUSED,
++	unsigned int stage ATTRIBUTE_UNUSED)
++{
++	return 1;
++}
++#endif /* TRACE_PEEPHOLE */
++
++
++/** Return 1 if it is OK to store a value of MODE in REGNO. */
++int
++m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
++{
++   /* Soft registers, as they are just memory, can really hold
++   values of any type.  However we restrict them to values of
++   size HImode or QImode to prevent exhausting them for larger
++   values.
++      Word values cannot be placed into the first soft register,
++   as it is the low byte that is being placed there, which
++   corrupts the (non-soft) register before it. */
++   if (M_REGNO_P (regno))
++   {
++      switch (GET_MODE_SIZE (mode))
++      {
++         case 1:
++            return 1;
++         case 2:
++            return regno != SOFT_M0_REGNUM;
++         default:
++            return 0;
++      }
++   }
++
++   /* VOIDmode can be stored anywhere */
++   else if (mode == VOIDmode)
++      return 1;
++
++   /* Zero is a reserved register, but problems occur if we don't
++   say yes here??? */
++   else if (regno == 0)
++      return 1;
++
++   /* For other registers, return true only if the requested size
++   exactly matches the hardware size. */
++   else if ((G_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 2))
++      return 1;
++   else if ((BYTE_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 1))
++      return 1;
++   else
++      return 0;
++}
++
++
++/* exp is the call expression.  DECL is the called function,
++ * or NULL for an indirect call */
++bool
++m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
++{
++	tree type, arg;
++   const char *name;
++	bool result = 0;
++	int argcount = 0;
++	int step = 1;
++
++	/* If there is no DECL, it is an indirect call.
++	 * Never optimize this??? */
++	if (decl == NULL)
++		goto done;
++
++	/* Never allow an interrupt handler to be optimized this way. */
++	if (m6809_function_has_type_attr_p (decl, "interrupt"))
++		goto done;
++
++	/* Skip sibcall if the type can't be found for
++	 * some reason */
++	step++;
++	name = IDENTIFIER_POINTER (DECL_NAME (decl));
++	type = TREE_TYPE (decl);
++	if (type == NULL)
++		goto done;
++
++	/* Skip sibcall if the target is a far function */
++	step++;
++	if (far_function_type_p (type) != NULL)
++		goto done;
++
++	/* Skip sibcall if the called function's arguments are
++	 * variable */
++	step++;
++	if (TYPE_ARG_TYPES (type) == NULL)
++		goto done;
++
++	/* Allow sibcalls in other cases. */
++	result = 1;
++done:
++	/* printf ("%s ok for sibcall? %s, step %d, args %d\n", name, result ? "yes" : "no", step, argcount); */
++	return result;
++}
++
++
++/** Emit code for the 'casesi' pattern.
++ * This pattern is only used in 8-bit mode, and can be disabled
++ * with -mold-case there as well.  The rationale for this is to
++ * do a better job than the simpler but well-tested 'tablejump'
++ * method.
++ *
++ * For small jumptables, where the switch expression is an
++ * 8-bit value, the lookup can be done more efficiently
++ * using the "B,X" style index mode. */
++void
++m6809_do_casesi (rtx index, rtx lower_bound, rtx range,
++	rtx table_label, rtx default_label)
++{
++	enum machine_mode mode;
++	rtx scaled;
++	rtx table_in_reg;
++
++	/* expr.c has to be patched so that it does not promote
++	 * the expression to SImode, but rather to HImode.
++	 * Fail now if that isn't the case. */
++	if (GET_MODE_SIZE (GET_MODE (index)) > GET_MODE_SIZE (HImode))
++		error ("try_casesi promotion bug");
++
++	/* Determine whether or not we are going to work primarily in
++	 * QImode or HImode.  This depends on the size of the index
++	 * into the lookup table.  QImode can only be used when the
++	 * index is less than 0x40, since it will be doubled but
++	 * must remain unsigned. */
++	if ((GET_CODE (range) == CONST_INT) && (INTVAL (range) < 0x40))
++		mode = QImode;
++	else
++		mode = HImode;
++
++	/* Convert to QImode if necessary */
++	if (mode == QImode)
++	{
++		index = gen_lowpart_general (mode, index);
++		lower_bound = gen_lowpart_general (mode, lower_bound);
++	}
++
++	/* Translate from case value to table index by subtraction */
++	if (lower_bound != const0_rtx)
++		index = expand_binop (mode, sub_optab, index, lower_bound,
++			NULL_RTX, 0, OPTAB_LIB_WIDEN);
++
++	/* Emit compare-and-jump to test for index out-of-range */
++	emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
++		default_label);
++
++	/* Put the table address is in a register */
++	table_in_reg = gen_reg_rtx (Pmode);
++	emit_move_insn (table_in_reg, gen_rtx_LABEL_REF (Pmode, table_label));
++
++	/* Emit table lookup and jump */
++	if (mode == QImode)
++	{
++		/* Scale the index */
++		scaled = gen_reg_rtx (QImode);
++		emit_insn (gen_ashlqi3 (scaled, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_short_offset (scaled, table_in_reg));
++	}
++	else
++	{
++		/* Scale the index */
++		emit_insn (gen_ashlhi3 (index, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_long_offset (index, table_in_reg));
++	}
++
++	/* Copied from expr.c */
++	if (!CASE_VECTOR_PC_RELATIVE && !flag_pic)
++		emit_barrier ();
++}
++
++
++/** Output the assembly code for a 32-bit add/subtract. */
++void
++m6809_output_addsi3 (int rtx_code, rtx *operands)
++{
++	rtx xoperands[8];
++	rtx dst = operands[0];
++
++	/* Prepare the operands by splitting each SImode into two HImodes
++	that can be operated independently.  The high word of operand 1
++	is further divided into two QImode components for use with 'adc'
++	style instructions. */
++	xoperands[7] = operands[3];
++
++	xoperands[0] = adjust_address (dst, HImode, 2);
++	xoperands[3] = adjust_address (dst, HImode, 0);
++
++#if 1
++	xoperands[2] = adjust_address (operands[1], HImode, 2);
++	xoperands[6] = adjust_address (operands[1], HImode, 0);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[1] = gen_int_mode (INTVAL (operands[2]) & 0xFFFF, HImode);
++		xoperands[4] = gen_int_mode ((INTVAL (operands[2]) >> 24) & 0xFF, QImode);
++		xoperands[5] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFF, QImode);
++	}
++	else
++	{
++		xoperands[1] = adjust_address (operands[2], HImode, 2);
++		xoperands[4] = adjust_address (operands[2], QImode, 0);
++		xoperands[5] = adjust_address (operands[2], QImode, 1);
++	}
++
++#endif
++
++#if 0
++	xoperands[1] = adjust_address (operands[1], HImode, 2);
++	xoperands[4] = adjust_address (operands[1], QImode, 0);
++	xoperands[5] = adjust_address (operands[1], QImode, 1);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[2] = gen_int_mode ((INTVAL (operands[2])) & 0xFFFF, HImode);
++		xoperands[6] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFFFF, HImode);
++	}
++	else
++	{
++		xoperands[2] = adjust_address (operands[2], HImode, 2);
++		xoperands[6] = adjust_address (operands[2], HImode, 0);
++	}
++#endif
++
++	/* Output the assembly code. */
++	if (rtx_code == PLUS)
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("add%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("adcb\t%5", xoperands);
++		output_asm_insn ("adca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++	else
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("sub%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("sbcb\t%5", xoperands);
++		output_asm_insn ("sbca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++}
++
++
++#if 0
++/** Output the assembly code for a 32-bit shift.
++Operands 0 and 1 must be the same rtx, forced by a matching
++constraint.  Operand 2 must be a CONST_INT.  Operand 3 is
++"d" in case a temporary reg is needed. */
++void
++m6809_output_shiftsi3 (int rtx_code, rtx *operands)
++{
++	unsigned int count = INTVAL (operands[2]) % 32;
++	unsigned int size = 4; /* sizeof (SImode) */
++	int s;
++	rtx xoperands[4];
++	int op;
++	int start, end, step;
++
++	/* Initialize */
++	if (rtx_code == ASHIFT)
++	{
++		start = size-1;
++		end = -1;
++		step = -1;
++	}
++	else
++	{
++		start = 0;
++		end = size;
++		step = 1;
++	}
++
++	xoperands[2] = operands[2];
++	xoperands[3] = operands[3];
++
++	if (count <= 0)
++		abort ();
++	if (rtx_code == ROTATE || rtx_code == ROTATERT)
++		abort ();
++
++	/* Extract bit shifts over 16 bits by HImode moves. */
++	if (count >= 16)
++	{
++	}
++
++	/* Extract bit shifts over 8 bits by QImode moves. */
++	if (count >= 8)
++	{
++	}
++
++	/* Iterate over the number of bits to be shifted. */
++	while (count > 0)
++	{
++		/* Each bit to be shifted requires 1 proper bit shift
++		and 3 rotates. */
++
++		/* First, do the arithmetic/logical shift.  Left shifts
++		start from the LSB; right shifts start from the MSB. */
++		xoperands[0] = adjust_address (operands[0], QImode, start);
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("asl\t%0", xoperands);
++				start--;
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("asr\t%0", xoperands);
++				start++;
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("lsr\t%0", xoperands);
++				start++;
++				break;
++		}
++
++		/* Next, rotate the other bytes */
++		for (s = start; s != end; s += step)
++		{
++			xoperands[0] = adjust_address (operands[0], QImode, s);
++			switch (rtx_code)
++			{
++				case ASHIFT:
++					output_asm_insn ("rol\t%0", xoperands);
++					break;
++				case ASHIFTRT:
++				case LSHIFTRT:
++					output_asm_insn ("ror\t%0", xoperands);
++					break;
++			}
++		}
++		count--;
++	}
++}
++#endif
++
++int
++power_of_two_p (unsigned int n)
++{
++	return (n & (n-1)) == 0;
++}
++
++
++int
++m6809_can_eliminate (int from, int to)
++{
++	if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
++		return !frame_pointer_needed;
++	return 1;
++}
++
++
++int
++m6809_initial_elimination_offset (int from, int to)
++{
++	switch (from)
++	{
++		case ARG_POINTER_REGNUM:
++			return get_frame_size () + m6809_get_regs_size (m6809_get_live_regs ());
++		case FRAME_POINTER_REGNUM:
++			return get_frame_size ();
++		default:
++			gcc_unreachable ();
++	}
++}
++
++
++bool
++m6809_frame_pointer_required (void)
++{
++	return false;
++}
++
++
++/* Defines the target-specific hooks structure. */
++struct gcc_target targetm = TARGET_INITIALIZER;
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.h gcc-4.6.4/gcc/config/m6809/m6809.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.h	2017-11-28 21:17:43.127091341 -0700
+@@ -0,0 +1,1336 @@
++/* Definitions of target machine for GNU compiler.  MC6809 version.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to egcs-1.1.2 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ changes for gcc-3.1.1 by ???
++
++ further changes for gcc-3.1.1 and beyond by Brian Dominy
++ (brian@oddchange.com)
++
++ even more changes for gcc-4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++
++/* Helper macros for creating strings with macros */
++#define C_STRING(x) C_STR(x)
++#define C_STR(x) #x
++
++/* Certain parts of GCC include host-side includes, which is bad.
++ * Some things that get pulled in need to be undone.
++ */
++#undef HAVE_GAS_HIDDEN
++
++/* Names to predefine in the preprocessor for this target machine.  */
++/*#define TARGET_CPU_CPP_BUILTINS() m6809_cpu_cpp_builtins () */
++#define TARGET_CPU_CPP_BUILTINS() do \
++	{ \
++		if (TARGET_6309) \
++		{ \
++			builtin_define_std ("__M6309__"); \
++			builtin_define_std ("__m6309__"); \
++		} \
++		else \
++		{ \
++			builtin_define_std ("__M6809__"); \
++			builtin_define_std ("__m6809__"); \
++		} \
++ \
++		if (TARGET_BYTE_INT) \
++			builtin_define_std ("__int8__"); \
++		else \
++			builtin_define_std ("__int16__"); \
++ \
++		switch (m6809_abi_version) \
++		{ \
++			case M6809_ABI_VERSION_STACK: \
++				builtin_define_std ("__regargs__"); \
++				builtin_define_std ("__ABI_STACK__"); \
++				break; \
++			case M6809_ABI_VERSION_REGS: \
++				builtin_define_std ("__ABI_REGS__"); \
++				break; \
++			case M6809_ABI_VERSION_BX: \
++				builtin_define_std ("__ABI_BX__"); \
++				break; \
++			default: \
++				break; \
++		} \
++ \
++		if (TARGET_WPC) \
++			builtin_define_std ("__WPC__"); \
++ \
++		if (TARGET_DRET) \
++			builtin_define_std ("__DRET__"); \
++	} while (0)
++
++/* As an embedded target, we have no libc.  */
++#ifndef inhibit_libc
++#define inhibit_libc
++#endif
++
++/* Print subsidiary information on the compiler version in use.  */
++#define TARGET_VERSION fprintf (stderr, " (MC6809)");
++
++/* Run-time compilation parameters selecting different hardware subsets.  */
++/*extern int target_flags; */
++extern short *reg_renumber;	/* def in local_alloc.c */
++
++/* Runtime current values of section names */
++extern int section_changed;
++extern char code_section_op[], data_section_op[], bss_section_op[];
++
++#define WARNING_OPT 0,
++/*extern const char *m6809_abi_version_ptr; */
++extern unsigned int m6809_soft_regs;
++extern unsigned int m6809_abi_version;
++
++/* ABI versions */
++
++#define M6809_ABI_VERSION_STACK 0
++#define M6809_ABI_VERSION_REGS 1
++#define M6809_ABI_VERSION_BX 2
++#define M6809_ABI_VERSION_LATEST  (M6809_ABI_VERSION_BX)
++
++/* Allow $ in identifiers */
++#define DOLLARS_IN_IDENTIFIERS 1
++
++/*--------------------------------------------------------------
++	Target machine storage layout
++--------------------------------------------------------------*/
++
++/* Define this if most significant bit is lowest numbered
++   in instructions that operate on numbered bit-fields.  */
++#define BITS_BIG_ENDIAN 0
++
++/* Define to 1 if most significant byte of a word is the lowest numbered. */
++#define BYTES_BIG_ENDIAN 1
++
++/* Define to 1 if most significant word of a multiword value is the lowest numbered. */
++#define WORDS_BIG_ENDIAN 1
++
++/* Number of bits in an addressible storage unit */
++#define BITS_PER_UNIT 8
++
++/* Width in bits of a "word", or the contents of a machine register.
++ * Although the 6809 has a few byte registers, define this to 16-bits
++ * since this is the natural size of most registers. */
++#define BITS_PER_WORD 16
++
++/* Width of a word, in units (bytes).  */
++#define UNITS_PER_WORD (BITS_PER_WORD/8)
++
++/* Width in bits of a pointer.  See also the macro `Pmode' defined below.  */
++#define POINTER_SIZE 16
++
++/* Allocation boundary (bits) for storing pointers in memory.  */
++#define POINTER_BOUNDARY 8
++
++/* Allocation boundary (bits) for storing arguments in argument list.  */
++/* PARM_BOUNDARY is divided by BITS_PER_WORD in expr.c -- tej */
++#define PARM_BOUNDARY 8
++
++/* Boundary (bits) on which stack pointer should be aligned.  */
++#define STACK_BOUNDARY 8
++
++/* Allocation boundary (bits) for the code of a function.  */
++#define FUNCTION_BOUNDARY 8
++
++/* Alignment of field after `int : 0' in a structure.  */
++#define EMPTY_FIELD_BOUNDARY 8
++
++/* Every structure's size must be a multiple of this.  */
++#define STRUCTURE_SIZE_BOUNDARY 8
++
++/* Largest mode size to use when putting an object, including
++ * a structure, into a register.  By limiting this to 16, no
++ * 32-bit objects will ever be allocated to a pair of hard
++ * registers.  This is a good thing, since there aren't that
++ * many of them.  32-bit objects are only needed for floats
++ * and "long long"s.  Larger values have been tried and did not
++ * work. */
++#define MAX_FIXED_MODE_SIZE 16
++
++/* No data type wants to be aligned rounder than this.  */
++#define BIGGEST_ALIGNMENT 8
++
++/* Define this if move instructions will actually fail to work
++   when given unaligned data.  */
++#define STRICT_ALIGNMENT 0
++
++/*--------------------------------------------------------------
++	 Standard register usage.
++--------------------------------------------------------------*/
++
++/* Register values as bitmasks.
++ * TODO : merge D_REGBIT and B_REGBIT, and treat this as the same
++ * register. */
++#define RSVD1_REGBIT    (1 << HARD_RSVD1_REGNUM)
++#define D_REGBIT			(1 << HARD_D_REGNUM)
++#define X_REGBIT			(1 << HARD_X_REGNUM)
++#define Y_REGBIT			(1 << HARD_Y_REGNUM)
++#define U_REGBIT			(1 << HARD_U_REGNUM)
++#define S_REGBIT			(1 << HARD_S_REGNUM)
++#define PC_REGBIT			(1 << HARD_PC_REGNUM)
++#define Z_REGBIT        (1 << HARD_Z_REGNUM)
++#define A_REGBIT			(1 << HARD_A_REGNUM)
++#define B_REGBIT			(1 << HARD_B_REGNUM)
++#define CC_REGBIT			(1 << HARD_CC_REGNUM)
++#define DP_REGBIT			(1 << HARD_DP_REGNUM)
++#define SOFT_FP_REGBIT  (1 << SOFT_FP_REGNUM)
++#define SOFT_AP_REGBIT  (1 << SOFT_AP_REGNUM)
++#define M_REGBIT(n)		(1 << (SOFT_M0_REGNUM + n))
++
++/* Macros for dealing with set of registers.
++ * A register set is just a bitwise-OR of all the register
++ * bitmask values. */
++
++/* Which registers can hold 8-bits */
++#define BYTE_REGSET \
++	(Z_REGBIT | A_REGBIT | D_REGBIT | CC_REGBIT | DP_REGBIT)
++
++/* Which registers can hold 16-bits.
++ * Note: D_REGBIT is defined as both an 8-bit and 16-bit register */
++#define WORD_REGSET \
++	(D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT | SOFT_FP_REGBIT | SOFT_AP_REGBIT | RSVD1_REGBIT)
++
++/* Returns nonzero if a given REGNO is in the REGSET. */
++#define REGSET_CONTAINS_P(regno, regset)  (((1 << (regno)) & (regset)) != 0)
++
++/* Defines related to the number of soft registers supported.
++ * The actual number used may be less depending on -msoft-reg-count.
++ * If you change one of these, you should change them all. */
++#define NUM_M_REGS 8
++#define M_REGS_FIXED 1, 1, 1, 1, 1, 1, 1, 1
++#define M_REGS_CALL_USED 1, 1, 1, 1, 1, 1, 1, 1
++#define HARD_M_REGNUMS \
++   SOFT_M0_REGNUM+0, SOFT_M0_REGNUM+1, SOFT_M0_REGNUM+2, SOFT_M0_REGNUM+3, \
++   SOFT_M0_REGNUM+4, SOFT_M0_REGNUM+5, SOFT_M0_REGNUM+6, SOFT_M0_REGNUM+7
++
++#define SOFT_M_REGBITS  (((1UL << NUM_M_REGS) - 1) << (SOFT_M0_REGNUM))
++
++/* Number of actual hardware registers.
++   The hardware registers are assigned numbers for the compiler
++   from 0 to just below FIRST_PSEUDO_REGISTER.
++   All registers that the compiler knows about must be given numbers,
++   even those that are not normally considered general registers.
++   Make sure the constant below matches the value of SOFT_M0_REGNUM;
++   for some reason, GCC won't compile if that name is used here directly. */
++#ifdef SOFT_M0_REGNUM
++#if (SOFT_M0_REGNUM != 14)
++#error "bad register numbering"
++#endif
++#endif
++#define FIRST_PSEUDO_REGISTER (14 + NUM_M_REGS)
++
++/* 1 for registers that have pervasive standard uses
++   and are not available for the register allocator.
++   The psuedoregisters (M_REGS) are declared fixed here, but
++   will be unfixed if -msoft-reg-count is seen later.  */
++#define FIXED_REGISTERS \
++    {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, M_REGS_FIXED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* 1 for registers not available across function calls.
++   These must include the FIXED_REGISTERS and also any
++   registers that can be used without being saved.
++   The latter must include the registers where values are returned
++   and the register where structure-value addresses are passed.
++   Aside from that, you can include as many other registers as you like.  */
++#define CALL_USED_REGISTERS \
++    {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, M_REGS_CALL_USED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* Return number of consecutive hard regs needed starting at reg REGNO
++   to hold something of mode MODE.
++	For the 6809, we distinguish between word-length and byte-length
++	registers. */
++#define HARD_REGNO_NREGS(REGNO, MODE) \
++   (REGSET_CONTAINS_P (REGNO, WORD_REGSET) ? \
++		((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : \
++      (GET_MODE_SIZE (MODE)))
++
++
++/* Value is 1 if hard register REGNO can hold a value
++of machine-mode MODE. */
++#define HARD_REGNO_MODE_OK(REGNO, MODE) m6809_hard_regno_mode_ok (REGNO, MODE)
++
++/* Value is 1 if it is a good idea to tie two pseudo registers
++   when one has mode MODE1 and one has mode MODE2.
++   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
++   for any hard reg, then this must be 0 for correct output.  */
++#define MODES_TIEABLE_P(MODE1, MODE2) 0
++
++/* Specify the registers used for certain standard purposes.
++   The values of these macros are register numbers.  */
++
++/* program counter if referenced as a register */
++#define PC_REGNUM HARD_PC_REGNUM
++
++/* Register to use for pushing function arguments.  */
++#define STACK_POINTER_REGNUM HARD_S_REGNUM
++
++/* Base register for access to local variables of the function.
++ * Before reload, FRAME_POINTER_REGNUM will be used.  Later,
++ * the elimination pass will convert these to STACK_POINTER_REGNUM
++ * if possible, or else HARD_FRAME_POINTER_REGNUM.  The idea is to
++ * avoid tying up a hard register (U) for the frame pointer if
++ * it can be eliminated entirely, making it available for use as
++ * a general register. */
++#define FRAME_POINTER_REGNUM       SOFT_FP_REGNUM
++#define HARD_FRAME_POINTER_REGNUM  HARD_U_REGNUM
++
++/* Define a table of possible eliminations.
++ * The idea is to try to avoid using hard registers for the argument
++ * and frame pointers if they can be derived from the stack pointer
++ * instead, which already has a hard register reserved for it.
++ *
++ * The order of entries in this table will try to convert
++ * ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM into stack pointer
++ * references first, but if that fails, they will be converted to use
++ * HARD_FRAME_POINTER_REGNUM.
++ */
++#define ELIMINABLE_REGS \
++{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
++
++/* #define CAN_ELIMINATE(FROM, TO) m6809_can_eliminate (FROM, TO) */
++
++/* Define how to offset the frame or argument pointer to turn it
++ * into a stack pointer reference.  This is based on the way that
++ * the frame is constructed in the function prologue. */
++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
++	(OFFSET) = m6809_initial_elimination_offset (FROM, TO)
++
++/* Base register for access to arguments of the function.
++ * This is only used prior to reload; no instructions will ever
++ * be output referring to this register. */
++#define ARG_POINTER_REGNUM SOFT_AP_REGNUM
++
++/* Register in which static-chain is passed to a function.  */
++#define STATIC_CHAIN_REGNUM HARD_Y_REGNUM
++
++/* #define CONDITIONAL_REGISTER_USAGE (m6809_conditional_register_usage ()) */
++
++/* Order in which hard registers are allocated to pseudos.
++ *
++ * Since the D register is the only valid reg for 8-bit values
++ * now, avoid using it for 16-bit values by putting it after all
++ * other 16-bits.
++ *
++ * Prefer X first since the first 16-bit function argument goes
++ * there.  We may be able to pass in to a subroutine without
++ * a copy.
++ *
++ * Prefer U over Y since instructions using Y take one extra
++ * byte, and thus one extra cycle to execute.
++ */
++#define REG_ALLOC_ORDER \
++   {  HARD_X_REGNUM, HARD_U_REGNUM, HARD_Y_REGNUM, HARD_D_REGNUM, \
++	   HARD_M_REGNUMS, HARD_S_REGNUM, HARD_PC_REGNUM, \
++		HARD_B_REGNUM, HARD_A_REGNUM, HARD_CC_REGNUM, \
++		HARD_DP_REGNUM, SOFT_FP_REGNUM, SOFT_AP_REGNUM, \
++		6, HARD_Z_REGNUM }
++
++/*--------------------------------------------------------------
++	classes of registers
++--------------------------------------------------------------*/
++
++/* Define the classes of registers for register constraints in the
++   machine description.  Also define ranges of constants.
++
++   One of the classes must always be named ALL_REGS and include all hard regs.
++   If there is more than one class, another class must be named NO_REGS
++   and contain no registers.
++
++   The name GENERAL_REGS must be the name of a class (or an alias for
++   another name such as ALL_REGS).  This is the class of registers
++   that is allowed by "g" or "r" in a register constraint.
++   Also, registers outside this class are allocated only when
++   instructions express preferences for them.
++
++   The classes must be numbered in nondecreasing order; that is,
++   a larger-numbered class must never be contained completely
++   in a smaller-numbered class.
++
++   For any two classes, it is very desirable that there be another
++   class that represents their union.  */
++   
++enum reg_class {
++    NO_REGS,    /* The trivial class with no registers in it */
++    D_REGS,     /* 16-bit (word (HI)) data (D) */
++    ACC_A_REGS, /* The A register */
++    ACC_B_REGS, /* The B register */
++	 X_REGS,     /* The X register */
++	 Z_REGS,     /* The Z (zero-bit) register */
++    Q_REGS,     /* 8-bit (byte (QI)) data (A,B) */
++    M_REGS,     /* 8-bit (byte (QI)) soft registers */
++	 CC_REGS,    /* 8-bit condition code register */
++    I_REGS,     /* An index register (A,B,D) */
++    T_REGS,     /* 16-bit addresses, not including stack or PC (X,Y,U) */
++    A_REGS,     /* 16-bit addresses (X,Y,U,S,PC) */
++	 S_REGS,     /* 16-bit soft registers (FP, AP) */
++	 P_REGS,     /* 16-bit pushable registers (D,X,Y,U); omit PC and S */
++    G_REGS,     /* 16-bit data and address (D,X,Y,U,S,PC) */
++    ALL_REGS,   /* All registers */
++    LIM_REG_CLASSES
++};
++
++#define N_REG_CLASSES (int) LIM_REG_CLASSES
++
++/* Since GENERAL_REGS is a smaller class than ALL_REGS,
++   it is not an alias to ALL_REGS, but to G_REGS. */
++#define GENERAL_REGS G_REGS
++
++/* Give names of register classes as strings for dump file.   */
++#define REG_CLASS_NAMES \
++ {  "NO_REGS", "D_REGS", "ACC_A_REGS", "ACC_B_REGS", "X_REGS", "Z_REGS", "Q_REGS", "M_REGS", \
++	 "CC_REGS", "I_REGS", "T_REGS", "A_REGS", "S_REGS", "P_REGS", "G_REGS", \
++	 "ALL_REGS" }
++
++/* Define which registers fit in which classes.
++   This is an initializer for a vector of HARD_REG_SET
++   of length N_REG_CLASSES.  */
++
++#define D_REGSET	(D_REGBIT)
++#define ACC_A_REGSET (A_REGBIT)
++#define ACC_B_REGSET (D_REGBIT)
++#define X_REGSET (X_REGBIT)
++#define Z_REGSET (Z_REGBIT)
++#define Q_REGSET (D_REGBIT | A_REGBIT)
++#define M_REGSET (SOFT_M_REGBITS)
++#define CC_REGSET (CC_REGBIT)
++#define I_REGSET (A_REGBIT | B_REGBIT | D_REGBIT)
++#define T_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT)
++#define A_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT)
++#define S_REGSET (SOFT_FP_REGBIT | SOFT_AP_REGBIT)
++#define P_REGSET (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT)
++#define G_REGSET \
++   (D_REGSET | Q_REGSET | I_REGSET | A_REGSET | M_REGSET | S_REGSET)
++#define ALL_REGSET (G_REGSET)
++
++#define REG_CLASS_CONTENTS { \
++	{0}, \
++	{D_REGSET}, \
++   {ACC_A_REGSET}, \
++   {ACC_B_REGSET}, \
++   {X_REGSET}, \
++   {Z_REGSET}, \
++	{Q_REGSET}, \
++	{M_REGSET}, \
++   {CC_REGSET}, \
++	{I_REGSET}, \
++	{T_REGSET}, \
++	{A_REGSET}, \
++	{S_REGSET}, \
++	{P_REGSET}, \
++	{G_REGSET}, \
++	{ALL_REGSET}, \
++}
++
++/* The same information, inverted.
++ * This is defined to use the REG_CLASS_CONTENTS defines above, so that
++ * these two sets of definitions are always consistent. */
++
++#define REGNO_REG_CLASS(REGNO) \
++  (D_REGNO_P (REGNO) ? D_REGS : \
++  (Z_REGNO_P (REGNO) ? Z_REGS : \
++  (ACC_A_REGNO_P (REGNO) ? ACC_A_REGS : \
++  (ACC_B_REGNO_P (REGNO) ? ACC_B_REGS : \
++  (X_REGNO_P (REGNO) ? X_REGS : \
++  (Q_REGNO_P (REGNO) ? Q_REGS : \
++  (M_REGNO_P (REGNO) ? M_REGS : \
++  (CC_REGNO_P (REGNO) ? CC_REGS : \
++  (I_REGNO_P (REGNO) ? I_REGS : \
++  (T_REGNO_P (REGNO) ? T_REGS : \
++  (A_REGNO_P (REGNO) ? A_REGS : \
++  (S_REGNO_P (REGNO) ? S_REGS : \
++  (P_REGNO_P (REGNO) ? P_REGS : \
++  (G_REGNO_P (REGNO) ? G_REGS : ALL_REGS))))))))))))))
++
++#define D_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, D_REGSET))
++#define ACC_A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_A_REGSET))
++#define ACC_B_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_B_REGSET))
++#define X_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, X_REGSET))
++#define Z_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Z_REGSET))
++#define Q_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Q_REGSET))
++#define M_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, M_REGSET))
++#define CC_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, CC_REGSET))
++#define I_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, I_REGSET))
++#define T_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, T_REGSET))
++#define A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, A_REGSET))
++#define S_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, S_REGSET))
++#define P_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, P_REGSET))
++#define G_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, G_REGSET))
++
++/* Macros that test an rtx 'X' to see if it's in a particular
++ * register class.  'X' need not be a REG necessarily. */
++
++#define D_REG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
++#define ACC_A_REG_P(X) (REG_P (X) && ACC_A_REGNO_P (REGNO (X)))
++#define ACC_B_REG_P(X) (REG_P (X) && ACC_B_REGNO_P (REGNO (X)))
++#define X_REG_P(X) (REG_P (X) && X_REGNO_P (REGNO (X)))
++#define Z_REG_P(X) (REG_P (X) && Z_REGNO_P (REGNO (X)))
++#define I_REG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
++#define T_REG_P(X) (REG_P (X) && T_REGNO_P (REGNO (X)))
++#define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
++#define S_REG_P(X) (REG_P (X) && S_REGNO_P (REGNO (X)))
++#define P_REG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
++#define Q_REG_P(X) (REG_P (X) && Q_REGNO_P (REGNO (X)))
++#define M_REG_P(X) (REG_P (X) && M_REGNO_P (REGNO (X)))
++#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
++
++/* Redefine this in terms of BYTE_REGSET */
++#define BYTE_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, BYTE_REGSET))
++
++/* The class value for index registers, and the one for base regs.  */
++#define INDEX_REG_CLASS I_REGS
++#define BASE_REG_CLASS A_REGS
++
++/* Get reg_class from a letter in the machine description.  */
++#define REG_CLASS_FROM_LETTER(C) \
++  (((C) == 'a' ? A_REGS : \
++   ((C) == 'd' ? D_REGS : \
++	((C) == 'x' ? I_REGS : \
++	((C) == 't' ? M_REGS : \
++	((C) == 'c' ? CC_REGS : \
++	((C) == 'A' ? ACC_A_REGS : \
++	((C) == 'B' ? ACC_B_REGS : \
++	((C) == 'v' ? X_REGS : \
++	((C) == 'u' ? S_REGS : \
++	((C) == 'U' ? P_REGS : \
++	((C) == 'T' ? T_REGS : \
++	((C) == 'z' ? Z_REGS : \
++   ((C) == 'q' ? Q_REGS : NO_REGS))))))))))))))
++
++/*--------------------------------------------------------------
++   The letters I through O in a register constraint string
++   can be used to stand for particular ranges of immediate operands.
++   This macro defines what the ranges are.
++   C is the letter, and VALUE is a constant value.
++   Return 1 if VALUE is in the range specified by C.
++
++   For the 6809, J, K, L are used for indexed addressing.
++   `I' is used for the constant 1.
++   `J' is used for the 5-bit offsets.
++   `K' is used for the 8-bit offsets.
++   `L' is used for the range of signed numbers that fit in 16 bits.
++   `M' is used for the exact value '8'.
++   `N' is used for the constant -1.
++   `O' is used for the constant 0.
++--------------------------------------------------------------*/
++
++#define CONST_OK_FOR_LETTER_P(VALUE, C) \
++  ((C) == 'I' ? ((VALUE) == 1) : \
++   (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
++   (C) == 'K' ? ((VALUE) >= -128 && (VALUE) <= 127) : \
++   (C) == 'L' ? ((VALUE) >= -32768 && (VALUE) <= 32767) : \
++   (C) == 'M' ? ((VALUE) == 8) : \
++   (C) == 'N' ? ((VALUE) == -1) : \
++   (C) == 'O' ? ((VALUE) == 0) : 0)
++
++/* Similar, but for floating constants, and defining letters G and H.
++   No floating-point constants are valid on MC6809.  */
++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
++   ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
++     && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
++
++/* Given an rtx X being reloaded into a reg required to be
++   in class CLASS, return the class of reg to actually use.
++   In general this is just CLASS; but on some machines
++   in some cases it is preferable to use a more restrictive class.  */
++#define PREFERRED_RELOAD_CLASS(X,CLASS) m6809_preferred_reload_class(X,CLASS)
++
++#define SMALL_REGISTER_CLASSES  1
++
++/* Return the maximum number of consecutive registers
++   needed to represent mode MODE in a register of class CLASS.  */
++#define CLASS_MAX_NREGS(CLASS, MODE) \
++    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++
++/*--------------------------------------------------------------
++	Stack layout; function entry, exit and calling.
++--------------------------------------------------------------*/
++
++/* Define this if pushing a word on the stack
++   makes the stack pointer a smaller address.  */
++#define STACK_GROWS_DOWNWARD
++
++
++/* Define this if the nominal address of the stack frame
++   is at the high-address end of the local variables;
++   that is, each additional local variable allocated
++   goes at a more negative offset in the frame.  */
++#define FRAME_GROWS_DOWNWARD 1
++
++
++/* Offset within stack frame to start allocating local variables at.
++   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
++   first local allocated.  Otherwise, it is the offset to the BEGINNING
++   of the first local allocated.  */
++#define STARTING_FRAME_OFFSET 0
++
++
++/* Always push stack arguments for now.  Accumulation is not yet working. */
++#define PUSH_ROUNDING(BYTES) (BYTES)
++
++
++/* Offset of first parameter from the argument pointer register value.
++ * ARG_POINTER_REGNUM is defined to point to the return address pushed
++ * onto the stack, so we must offset by 2 bytes to get to the arguments. */
++#define FIRST_PARM_OFFSET(FNDECL) 2
++
++/* Value is 1 if returning from a function call automatically
++   pops the arguments described by the number-of-args field in the call.
++   FUNTYPE is the data type of the function (as a tree),
++   or for a library call it is an identifier node for the subroutine name. */
++/* #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 */
++
++/* Define how to find the value returned by a function.
++   VALTYPE is the data type of the value (as a tree).
++   If the precise function being called is known, FUNC is its FUNCTION_DECL;
++   otherwise, FUNC is 0.  */
++#define FUNCTION_VALUE(VALTYPE, FUNC) m6809_function_value (VALTYPE, FUNC)
++
++/* Define how to find the value returned by a library function
++   assuming the value has mode MODE.  */
++
++/* All return values are in the X-register. */
++#define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, HARD_X_REGNUM)
++
++/* Define this if using the nonreentrant convention for returning
++   structure and union values.  No; it is inefficient and buggy. */
++#undef PCC_STATIC_STRUCT_RETURN
++
++/* 1 if N is a possible register number for a function value. */
++#define FUNCTION_VALUE_REGNO_P(N) m6809_function_value_regno_p (N)
++
++/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
++   more than one register.  */
++#define NEEDS_UNTYPED_CALL 1
++
++/* 1 if N is a possible register number for function argument passing. */
++#define FUNCTION_ARG_REGNO_P(N) \
++	((m6809_abi_version != M6809_ABI_VERSION_STACK) ? \
++   	(((N) == HARD_D_REGNUM) || ((N) == HARD_X_REGNUM)) : \
++		0)
++
++/*--------------------------------------------------------------
++	Argument Lists
++--------------------------------------------------------------*/
++
++/* Cumulative arguments are tracked in a single integer, 
++ * which is the number of bytes of arguments scanned so far,
++ * plus which registers have already been used.  The register
++ * info is kept in some of the upper bits */
++#define CUMULATIVE_ARGS unsigned int
++
++#define CUM_STACK_ONLY 0x80000000
++#define CUM_X_MASK     0x40000000
++#define CUM_B_MASK     0x20000000
++#define CUM_STACK_INVALID 0x10000000
++#define CUM_STACK_MASK 0xFFFFFFF
++
++#define CUM_ADVANCE_8BIT(cum) \
++	(((cum) & CUM_B_MASK) ? (cum)++ : ((cum) |= CUM_B_MASK))
++
++#define CUM_ADVANCE_16BIT(cum) \
++	(((cum) & CUM_X_MASK) ? (cum) += 2 : ((cum) |= CUM_X_MASK))
++
++/* 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.
++	N_NAMED was added in gcc 3.4 and is not used currently. */
++#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED) \
++	((CUM) = m6809_init_cumulative_args (CUM, FNTYPE, LIBNAME))
++
++#define FUNCTION_ARG_SIZE(MODE, TYPE)	\
++  ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)	\
++   : (unsigned) int_size_in_bytes (TYPE))
++
++/* 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.)  */
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
++	 (((MODE == QImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_8BIT (CUM) : \
++	  ((MODE == HImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_16BIT (CUM) : \
++	  ((CUM) = ((CUM) + (TYPE ? int_size_in_bytes (TYPE) : 2))))
++
++/* Define where to put the arguments to a function.
++   Value is zero to push the argument on the stack,
++   or a hard register rtx in which to store the argument.
++	This macro is used _before_ FUNCTION_ARG_ADVANCE.
++
++	For the 6809, the first 8-bit function argument can be placed into B,
++	and the first 16-bit arg can go into X.  All other arguments
++	will be pushed onto the stack.
++
++	Command-line options can adjust this behavior somewhat.
++ */
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++	((MODE == VOIDmode) ? NULL_RTX : \
++	((MODE == BLKmode) || (GET_MODE_SIZE (MODE) > 2)) ? NULL_RTX : \
++	((MODE == QImode) && !((CUM) & (CUM_STACK_ONLY | CUM_B_MASK))) ? \
++		gen_rtx_REG (QImode, HARD_D_REGNUM) : \
++	((MODE == HImode) && !((CUM) & (CUM_STACK_ONLY | CUM_X_MASK))) ?  \
++		gen_rtx_REG (HImode, HARD_X_REGNUM) : m6809_function_arg_on_stack (&CUM))
++
++/* Output assembler code to FILE to increment profiler label # LABELNO
++   for profiling a function entry.  */
++#define FUNCTION_PROFILER(FILE, LABELNO) \
++   fprintf (FILE, "\tldd\t#LP%u\n\tjsr\tmcount\n", (LABELNO));
++
++/* Stack pointer must be correct on function exit */
++#define EXIT_IGNORE_STACK 0
++
++/*****************************************************************************
++**
++** Trampolines for Nested Functions
++**
++*****************************************************************************/
++
++/* Length in units of the trampoline for entering a nested function.  */
++#define TRAMPOLINE_SIZE 7
++
++/*--------------------------------------------------------------
++	Addressing modes,
++	and classification of registers for them.
++--------------------------------------------------------------*/
++
++/* 6809 has postincrement and predecrement addressing modes */
++#define HAVE_POST_INCREMENT  1
++#define HAVE_PRE_DECREMENT  1
++
++/* Whether or not to use index registers is configurable.
++ * Experiments show that things work better when this is off, so
++ * that's the way it is for now. */
++#undef USE_INDEX_REGISTERS
++
++
++/* Macros to check register numbers against specific register classes.  */
++#define REG_VALID_FOR_BASE_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && A_REGNO_P (REGNO))
++
++/* MC6809 index registers do not allow scaling, */
++/* but there is "accumulator-offset" mode. */
++#ifdef USE_INDEX_REGISTERS
++#define REG_VALID_FOR_INDEX_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && I_REGNO_P (REGNO))
++#else
++#define REG_VALID_FOR_INDEX_P(REGNO) 0
++#endif
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_BASE_P (REGNO) \
++	|| (REGNO) == FRAME_POINTER_REGNUM \
++	|| (REGNO) == HARD_FRAME_POINTER_REGNUM \
++	|| (REGNO) == ARG_POINTER_REGNUM \
++	|| (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_INDEX_P (REGNO) \
++	|| (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_BASE_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_INDEX_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_BASE_STRICT_P (REGNO)
++
++#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_INDEX_STRICT_P (REGNO)
++
++#define REG_OK_FOR_BASE_STRICT_P(X)     REGNO_OK_FOR_BASE_STRICT_P (REGNO (X))
++#define REG_OK_FOR_BASE_NONSTRICT_P(X)  REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_STRICT_P(X)    REGNO_OK_FOR_INDEX_STRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_NONSTRICT_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (X))
++
++#ifndef REG_OK_STRICT
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_NONSTRICT_P(X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_NONSTRICT_P(X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#else
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_STRICT_P (X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_STRICT_P (X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#endif
++
++/* Maximum number of registers that can appear in a valid memory address */
++#ifdef USE_INDEX_REGISTERS
++#define MAX_REGS_PER_ADDRESS 2
++#else
++#define MAX_REGS_PER_ADDRESS 1
++#endif
++
++/* 1 if X is an rtx for a constant that is a valid address.
++ * We allow any constant, plus the sum of any two constants (this allows
++ * offsetting a symbol ref) */
++#define CONSTANT_ADDRESS_P(X) \
++	((CONSTANT_P (X)) \
++	|| ((GET_CODE (X) == PLUS) \
++	      && (CONSTANT_P (XEXP (X, 0))) && (CONSTANT_P (XEXP (X, 1)))))
++
++/* Nonzero if the constant value X is a legitimate general operand.
++   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
++/* Any single-word constant is ok; the only contexts
++   allowing general_operand of mode DI or DF are movdi and movdf. */
++#define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
++
++/* Nonzero if the X is a legitimate immediate operand in PIC mode. */
++#define LEGITIMATE_PIC_OPERAND_P(X)	!symbolic_operand (X, VOIDmode)
++
++/*--------------------------------------------------------------
++	Test for valid memory addresses
++--------------------------------------------------------------*/
++/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
++   that is a valid memory address for an instruction.
++   The MODE argument is the machine mode for the MEM expression
++   that wants to use this address. */
++
++/*--------------------------------------------------------------
++   Valid addresses are either direct or indirect (MEM) versions
++   of the following forms.
++	constant		N
++	register		,X
++	constant indexed	N,X
++	accumulator indexed	D,X
++	auto_increment		,X++
++	auto_decrement		,--X
++--------------------------------------------------------------*/
++
++#define REGISTER_ADDRESS_P(X) \
++  (REG_P (X) && REG_OK_FOR_BASE_P (X))
++
++#define EXTENDED_ADDRESS_P(X) \
++    CONSTANT_ADDRESS_P (X) \
++
++#define LEGITIMATE_BASE_P(X) \
++  ((REG_P (X) && REG_OK_FOR_BASE_P (X))	\
++   || (GET_CODE (X) == SIGN_EXTEND			\
++       && GET_CODE (XEXP (X, 0)) == REG			\
++       && GET_MODE (XEXP (X, 0)) == HImode		\
++       && REG_OK_FOR_BASE_P (XEXP (X, 0))))
++
++#define LEGITIMATE_OFFSET_P(X) \
++    (CONSTANT_ADDRESS_P (X) || (REG_P (X) && REG_OK_FOR_INDEX_P (X)))
++
++/* 1 if X is the sum of a base register and an offset. */
++#define INDEXED_ADDRESS(X) \
++   ((GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 0)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 1))) \
++   || (GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 1)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 0))))
++
++#define STACK_REG_P(X) (REG_P(X) && REGNO(X) == HARD_S_REGNUM)
++
++#define STACK_PUSH_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == PRE_DEC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define STACK_POP_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == POST_INC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define PUSH_POP_ADDRESS_P(X) \
++    (((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
++	&& (LEGITIMATE_BASE_P (XEXP (X, 0))))
++
++/* Go to ADDR if X is a valid address. */
++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
++{ \
++  if (REGISTER_ADDRESS_P(X)) goto ADDR; \
++  if (PUSH_POP_ADDRESS_P (X)) goto ADDR; \
++  if (EXTENDED_ADDRESS_P (X)) goto ADDR; \
++  if (INDEXED_ADDRESS (X)) goto ADDR; \
++  if (MEM_P (X) && REGISTER_ADDRESS_P(XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && PUSH_POP_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && EXTENDED_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && INDEXED_ADDRESS (XEXP (X, 0))) goto ADDR; \
++}
++
++/*--------------------------------------------------------------
++	Address Fix-up
++--------------------------------------------------------------*/
++/* Go to LABEL if ADDR (a legitimate address expression)
++   has an effect that depends on the machine mode it is used for.
++	In the latest GCC, this case is already handled by the core code
++	so no action is required here. */
++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
++
++
++/*--------------------------------------------------------------
++	Miscellaneous Parameters
++--------------------------------------------------------------*/
++/* Specify the machine mode that this machine uses
++   for the index in the tablejump instruction.  */
++#define CASE_VECTOR_MODE Pmode
++
++/* Define this as 1 if `char' should by default be signed; else as 0.  */
++#define DEFAULT_SIGNED_CHAR 0
++
++/* This flag, if defined, says the same insns that convert to a signed fixnum
++   also convert validly to an unsigned one.  */
++#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
++
++/* Max number of bytes we can move from memory to memory/register
++   in one reasonably fast instruction.  */
++#define MOVE_MAX 2
++
++/* Int can be 8 or 16 bits (default is 16) */
++#define INT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Short is always 16 bits */
++#define SHORT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Size (bits) of the type "long" on target machine */
++#define LONG_TYPE_SIZE (TARGET_BYTE_INT ? 16 : 32)
++
++/* Size (bits) of the type "long long" on target machine */
++#define LONG_LONG_TYPE_SIZE 32
++
++/* Size (bits) of the type "char" on target machine */
++#define CHAR_TYPE_SIZE 8
++
++/* Size (bits) of the type "float" on target machine */
++#define FLOAT_TYPE_SIZE 32
++
++/* Size (bits) of the type "double" on target machine.
++ * Note that the C standard does not require that doubles
++ * hold any more bits than float.  Since the 6809 has so few
++ * registers, we cannot really support more than 32-bits. */
++#define DOUBLE_TYPE_SIZE 32 
++
++/* Size (bits) of the type "long double" on target machine */
++#define LONG_DOUBLE_TYPE_SIZE 32
++
++/* Define the type used for "size_t".  With a 64KB address space,
++ * only a 16-bit value here makes sense. */
++#define SIZE_TYPE (TARGET_BYTE_INT ? "long unsigned int" : "unsigned int")
++
++/* Likewise, the difference between two pointers is also a 16-bit
++ * signed value. */
++#define PTRDIFF_TYPE (TARGET_BYTE_INT ? "long int" : "int")
++
++/* Nonzero if access to memory by bytes is slow and undesirable.  */
++#define SLOW_BYTE_ACCESS 0
++
++/* Define if shifts truncate the shift count
++   which implies one can omit a sign-extension or zero-extension
++   of a shift count.  */
++#define SHIFT_COUNT_TRUNCATED 0
++
++/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
++   is done just by pretending it is already truncated.  */
++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
++
++/* It is as good to call a constant function address as to
++   call an address kept in a register. */
++#define NO_FUNCTION_CSE
++
++/* Specify the machine mode that pointers have.
++   After generation of rtl, the compiler makes no further distinction
++   between pointers and any other objects of this machine mode.  */
++#define Pmode HImode
++
++/* A function address in a call instruction
++   is a byte address (for indexing purposes)
++   so give the MEM rtx a byte's mode.  */
++#define FUNCTION_MODE HImode
++
++/* Define the cost of moving a value from a register in CLASS1
++ * to CLASS2, of a given MODE.
++ *
++ * On the 6809, hard register transfers are all basically equivalent.
++ * But soft register moves are treated more like memory moves. */
++#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
++	(((CLASS1 == M_REGS) || (CLASS2 == M_REGS)) ? 4 : 7)
++
++/* Define the cost of moving a value between a register and memory. */
++#define MEMORY_MOVE_COST(MODE, CLASS, IN) 5
++
++/* Check a `double' value for validity for a particular machine mode.  */
++
++#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
++  ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
++
++
++/*--------------------------------------------------------------
++	machine-dependent
++--------------------------------------------------------------*/
++/* Tell final.c how to eliminate redundant test instructions.  */
++
++/* Here we define machine-dependent flags and fields in cc_status
++   (see `conditions.h').  */
++
++/* Store in cc_status the expressions
++   that the condition codes will describe
++   after execution of an instruction whose pattern is EXP.
++   Do not alter them if the instruction would not alter the cc's.  */
++
++/* On the 6809, most of the insns to store in an address register
++   fail to set the cc's.  However, in some cases these instructions
++   can make it possibly invalid to use the saved cc's.  In those
++   cases we clear out some or all of the saved cc's so they won't be used.  */
++
++#define NOTICE_UPDATE_CC(EXP, INSN) \
++  notice_update_cc((EXP), (INSN))
++
++/*****************************************************************************
++**
++** pragma support
++**
++*****************************************************************************/
++
++#if 0
++#define REGISTER_TARGET_PRAGMAS() \
++do { \
++	extern void pragma_section PARAMS ((cpp_reader *)); \
++	c_register_pragma (0, "section", pragma_section); \
++} while (0)
++
++#endif
++
++/*--------------------------------------------------------------
++	ASSEMBLER FORMAT
++--------------------------------------------------------------*/
++
++#define FMT_HOST_WIDE_INT "%ld"
++
++/* Output to assembler file text saying following lines
++   may contain character constants, extra white space, comments, etc.  */
++#define ASM_APP_ON ";----- asm -----\n"
++
++/* Output to assembler file text saying following lines
++   no longer contain unusual constructs.  */
++#define ASM_APP_OFF ";--- end asm ---\n"
++
++/* Use a semicolon to begin a comment. */
++#define ASM_COMMENT_START "; "
++
++/* Output assembly directives to switch to section 'name' */
++#undef TARGET_ASM_NAMED_SECTION
++#define TARGET_ASM_NAMED_SECTION	m6809_asm_named_section
++
++#undef TARGET_HAVE_NAMED_SECTION
++#define TARGET_HAVE_NAMED_SECTION m6809_have_named_section
++
++/* Output before read-only data.  */
++#define TEXT_SECTION_ASM_OP (code_section_op)
++
++/* Output before writable data.  */
++#define DATA_SECTION_ASM_OP (data_section_op)
++
++/* Output before uninitialized data.  */
++#define BSS_SECTION_ASM_OP (bss_section_op)
++
++/* Support the ctors and dtors sections for g++.  */
++ 
++#undef CTORS_SECTION_ASM_OP
++#define CTORS_SECTION_ASM_OP    "\t.area .ctors"
++#undef DTORS_SECTION_ASM_OP
++#define DTORS_SECTION_ASM_OP    "\t.area .dtors"
++
++
++#undef DO_GLOBAL_CTORS_BODY
++#undef DO_GLOBAL_DTORS_BODY
++
++#define HAS_INIT_SECTION
++
++/* This is how to output an assembler line
++   that says to advance the location counter
++   to a multiple of 2**LOG bytes.  */
++
++#define ASM_OUTPUT_ALIGN(FILE,LOG) \
++  if ((LOG) > 1) \
++    fprintf (FILE, "\t.bndry %u\n", 1 << (LOG))
++
++/* The .set foo,bar construct doesn't work by default */
++#undef SET_ASM_OP
++#define ASM_OUTPUT_DEF(FILE, LABEL1, LABEL2) \
++  do { \
++      assemble_name (FILE, LABEL1); \
++      fputs ("\tequ\t", FILE); \
++      assemble_name (FILE, LABEL2); \
++      fputc ('\n', FILE); \
++  } while (0)
++
++/* How to refer to registers in assembler output.
++   This sequence is indexed by compiler's hard-register-number (see above).  */
++#define MNAME(x) [SOFT_M0_REGNUM+(x)] = "*m" C_STRING(x) ,
++
++#define REGISTER_NAMES { \
++	[HARD_D_REGNUM]= "d", \
++	[HARD_X_REGNUM]= "x", \
++	[HARD_Y_REGNUM]= "y", \
++	[HARD_U_REGNUM]= "u", \
++	[HARD_S_REGNUM]= "s", \
++	[HARD_PC_REGNUM]= "pc", \
++	[HARD_A_REGNUM]= "a", \
++	[HARD_B_REGNUM]= "b", \
++	[HARD_CC_REGNUM]= "cc",\
++	[HARD_DP_REGNUM]= "dp", \
++	[SOFT_FP_REGNUM]= "soft_fp", \
++	[SOFT_AP_REGNUM]= "soft_ap", \
++	MNAME(0) MNAME(1) MNAME(2) MNAME(3) \
++	MNAME(4) MNAME(5) MNAME(6) MNAME(7) \
++	[HARD_RSVD1_REGNUM] = "-", \
++	[HARD_Z_REGNUM] = "z" /* bit 2 of CC */ }
++
++/*****************************************************************************
++**
++** Debug Support
++**
++*****************************************************************************/
++
++/* Default to DBX-style debugging */
++#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
++
++#define DBX_DEBUGGING_INFO
++
++#define DEFAULT_GDB_EXTENSIONS 0
++
++#define ASM_STABS_OP ";\t.stabs\t"
++#define ASM_STABD_OP ";\t.stabd\t"
++#define ASM_STABN_OP ";\t.stabn\t"
++
++#define DBX_CONTIN_LENGTH 54
++
++#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(ASMFILE, FILENAME) \
++do { \
++	const char *p = FILENAME; \
++	while ((p = strchr (p, '/')) != NULL) { \
++		p = FILENAME = p+1; \
++	} \
++  fprintf (ASMFILE, "%s", ASM_STABS_OP); \
++  output_quoted_string (ASMFILE, FILENAME); \
++  fprintf (ASMFILE, ",%d,0,0,", N_SO); \
++  assemble_name (ASMFILE, ltext_label_name); \
++  fputc ('\n', ASMFILE); \
++  switch_to_section (text_section); \
++  (*targetm.asm_out.internal_label) (ASMFILE, "Ltext", 0); \
++} while (0)
++
++/* With -g, GCC sometimes outputs string literals that are longer than
++ * the assembler can handle.  Without actual debug support, these are
++ * not really required.  Redefine the function to output strings to
++ * output as much as possible. */
++#define OUTPUT_QUOTED_STRING(FILE, STR) m6809_output_quoted_string (FILE, STR)
++
++/*****************************************************************************
++**
++** Output and Generation of Labels
++**
++*****************************************************************************/
++
++/* Prefixes for various assembly-time objects */
++
++#define REGISTER_PREFIX ""
++
++#define LOCAL_LABEL_PREFIX ""
++
++#define USER_LABEL_PREFIX "_"
++
++#define IMMEDIATE_PREFIX "#"
++
++/* This is how to output the definition of a user-level label named NAME,
++   such as the label on a static function or variable NAME.  */
++
++#define ASM_OUTPUT_LABEL(FILE,NAME) \
++do { \
++  if (section_changed) { \
++	  fprintf (FILE, "\n%s\n\n", code_section_op); \
++     section_changed = 0; \
++  } \
++  assemble_name (FILE, NAME); \
++  fputs (":\n", FILE); \
++} while (0)
++
++/* This is how to output the label for a function definition.  It
++   invokes ASM_OUTPUT_LABEL, but may examine the DECL tree node for
++	other properties. */
++#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
++  m6809_declare_function_name (FILE,NAME,DECL)
++
++/* This is how to output a command to make the user-level label
++    named NAME defined for reference from other files.  */
++
++#define GLOBAL_ASM_OP "\t.globl "
++
++/* This is how to output a reference to a user label named NAME. */
++#define ASM_OUTPUT_LABELREF(FILE,NAME) \
++  fprintf (FILE, "_%s", NAME)
++
++/* This is how to output a reference to a symbol ref
++ * Check to see if the symbol is in the direct page */
++#define ASM_OUTPUT_SYMBOL_REF(FILE,sym) \
++{ \
++	print_direct_prefix (FILE, sym); \
++	assemble_name (FILE, XSTR (sym, 0)); \
++}
++
++/* External references aren't necessary, so don't emit anything */
++#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)
++
++/* This is how to store into the string LABEL
++   the symbol_ref name of an internal numbered label where
++   PREFIX is the class of label and NUM is the number within the class.
++   This is suitable for output with `assemble_name'.  */
++#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
++  sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long int)NUM)
++
++/* This is how to output an assembler line defining an `int' constant.  */
++#define ASM_OUTPUT_INT(FILE,VALUE) \
++( fprintf (FILE, "\t.word "), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* Likewise for `char' and `short' constants.  */
++#define ASM_OUTPUT_SHORT(FILE,VALUE) \
++( fprintf (FILE, "\t.word "), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* This is how to output a string. */ 
++#define ASM_OUTPUT_ASCII(FILE,STR,SIZE) m6809_output_ascii (FILE, STR, SIZE)
++
++/* This is how to output an insn to push a register on the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
++   fprintf (FILE, "\tpshs\t%s\n", reg_names[REGNO])
++
++/* This is how to output an insn to pop a register from the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
++   fprintf (FILE, "\tpuls\t%s\n", reg_names[REGNO])
++
++/* This is how to output an element of a case-vector that is absolute. */
++
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++  fprintf (FILE, "\t.word L%u\n", VALUE)
++
++/* This is how to output an element of a case-vector that is relative. */
++
++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
++  fprintf (FILE, "\t.word L%u-L%u\n", VALUE, REL)
++
++
++/*****************************************************************************
++**
++** Assembler Commands for Alignment
++**
++*****************************************************************************/
++
++/* ASM_OUTPUT_SKIP is supposed to zero initialize the data. */
++#define ASM_OUTPUT_SKIP(FILE,SIZE) \
++  do { \
++    fprintf (FILE, "\tzmb\t%d\t;skip space\n", SIZE); \
++  } while (0)
++
++/* This says how to output an assembler line
++   to define a global common symbol.  */
++
++#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
++  do { \
++  switch_to_section (bss_section); \
++  fputs ("\t.globl\t", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fputs ("\n", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* This says how to output an assembler line
++   to define a local common symbol.  */
++
++#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
++do { \
++  switch_to_section (bss_section); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* Store in OUTPUT a string (made with alloca) containing
++   an assembler-name for a local static variable named NAME.
++   LABELNO is an integer which is different for each call.  */
++
++#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
++( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
++  sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long int)(LABELNO)))
++
++/* Print an instruction operand X on file FILE.
++   CODE is the code from the %-spec for printing this operand.
++   If `%z3' was used to print operand 3, then CODE is 'z'. */
++#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
++
++/* Print a memory operand whose address is X, on file FILE. */
++#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
++
++/* Don't let stack pushes build up too much. */
++#define MAX_PENDING_STACK 8
++
++/* Define values for builtin operations */
++enum m6809_builtins
++{
++	M6809_SWI,
++	M6809_SWI2,
++	M6809_SWI3,
++	M6809_CWAI,
++	M6809_SYNC,
++	M6809_ADD_CARRY,
++	M6809_SUB_CARRY,
++	M6809_ADD_DECIMAL,
++	M6809_NOP,
++	M6809_BLOCKAGE
++};
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.md gcc-4.6.4/gcc/config/m6809/m6809.md
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.md	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,2358 @@
++;; GCC machine description for Motorola 6809
++;; Copyright (C) 1989, 2005, 2006, 2007, 2008,
++;; 2009 Free Software Foundation, Inc.
++;;
++;; Mostly by Brian Dominy (brian@oddchange.com) with substantial renovations
++;; by William Astle (lost@l-w.ca).
++;;
++;; Based on earlier work by Tom Jones (jones@sal.wisc.edu) and
++;; Matthias Doerfel (msdoerfe@informatik.uni-erlangen.de)
++;;
++;; 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/>.
++;;
++;; General information:
++;; --------------------
++;; * This backend is mostly a rewrite from earlier (3.1.1 and before)
++;; versions.
++;;
++;; * The 'A' and 'B' registers are treated as a single register by the
++;; register allocator; hence, the instruction templates assume that
++;; both can be modified if either one is available for use.  No
++;; attempt is made to split instructions to refer to a particular half
++;; of the register.  It is always referred to as the 'D' register, even
++;; in QImode (when it will be displayed as 'B').
++;;
++;; * There is full support for proper branch instruction generation,
++;; based on instruction lengths.  However, many instruction patterns
++;; are still overloaded to emit lots of real instructions, which can
++;; make the length calculation difficult; in those cases, I've tried
++;; to be pessimistic and assume the worst-case.
++;;
++;; * The instruction type attributes are only defined for branch
++;; vs. non branch instructions for now, since there is seemingly no
++;; reason to define these for other types anyway.
++;;
++;; * The limited number of total registers presents the greatest
++;; challenge.  There are 'soft registers' -- memory locations
++;; used to simulate real regs -- which can be helpful.
++;;
++;; * Position-independent code (PIC) is supported and has been tested
++;; but not to the extent of absolute code generation.
++;;
++;; * All of the 6809 special opcodes, e.g. SWI and SYNC, are defined
++;; as UNSPEC instructions, and can be accessed from C code using
++;; __builtin_xxxx() style functions.
++;;
++;; What still needs to be done:
++;; ----------------------------
++;; * Replace remaining instances of (define_peephole) with
++;; (define_peephole2), or remove them completely if they are not
++;; matching anyway.  Add more peepholes for things actually encountered.
++;;
++;; * Indexing addressing can lead to crashes in complex functions when
++;; register pressure is high.  Only the 'D' register can actually be
++;; used as an index register, and its demand by other instructions
++;; can sometimes mean that it is impossible to satisfy constraints.
++;; Currently, indexing is completely disabled to avoid these types
++;; of problems, although code is slightly more inefficient in some
++;; working cases.
++;;
++;; * 32-bit math is terribly inefficient.
++;;
++
++
++;;--------------------------------------------------------------------
++;;-  Constants
++;;--------------------------------------------------------------------
++
++;
++; Define constants for hard register numbers.
++;
++(define_constants [
++  (HARD_RSVD1_REGNUM 0)
++  (HARD_X_REGNUM 1) (HARD_Y_REGNUM 2) (HARD_U_REGNUM 3)
++  (HARD_S_REGNUM 4) (HARD_PC_REGNUM 5) (HARD_D_REGNUM 6)
++  (HARD_Z_REGNUM 7)
++  (HARD_A_REGNUM 8) (HARD_B_REGNUM 9)
++  (HARD_CC_REGNUM 10) (HARD_DP_REGNUM 11)
++  (SOFT_FP_REGNUM 12) (SOFT_AP_REGNUM 13)
++  (SOFT_M0_REGNUM 14) (SOFT_M1_REGNUM 15)
++  (SOFT_M2_REGNUM 16) (SOFT_M3_REGNUM 17)
++])
++
++
++;
++; The range in which a short branch insn can be used.
++;
++(define_constants [
++  (MIN_SHORT_BRANCH_OFFSET -127)
++  (MAX_SHORT_BRANCH_OFFSET 128)
++])
++
++
++;
++; The lengths of various types of real 6809 instructions.
++;
++; By default, ordinary insns are 4 bytes long.  This is often not
++; right, and the insn patterns below will redefine this to the
++; correct value.
++;
++; Branch instruction lengths (conditional and unconditionals) are
++; well known and declared here.  The short insns are used when the
++; offset is within the range declared above (between MIN_SHORT
++; and MAX_SHORT) ; otherwise the long form is used.
++;
++(define_constants [
++  (DEFAULT_INSN_LENGTH 4)
++  (SHORT_CBRANCH_LENGTH 2)
++  (LONG_CBRANCH_LENGTH 4)
++  (SHORT_BRANCH_LENGTH 2)
++  (LONG_BRANCH_LENGTH 3)
++])
++
++
++;
++; Constants for insn cycle counts.
++; Note that these counts all assume 1-byte opcodes.  2-byte
++; opcodes require 1 extra cycles for fetching the extra byte.
++;
++(define_constants [
++  ;; The default insn length, when it cannot be calculated.
++  ;; Take a conservative approach and estimate high.
++  (DEFAULT_INSN_CYCLES 10)
++
++  ;; Cycle counts for ALU and load operations.
++  (ALU_INHERENT_CYCLES 2)
++  (ALU_IMMED_CYCLES 2)
++  (ALU_DIRECT_CYCLES 4)
++  (ALU_INDEXED_BASE_CYCLES 4)
++  (ALU_EXTENDED_CYCLES 5)
++
++  ;; If an ALU operation is on a 16-bit register (D), then
++  ;; add this number of cycles to the total count.
++  (ALU_16BIT_CYCLES 2)
++
++  ;; A load of a 16-bit register incurs this extra amount.
++  (LOAD_16BIT_CYCLES 1)
++
++  ;; Cycle counts for memory-only operations (bit shifts, clear, test)
++  (MEM_DIRECT_CYCLES 6)
++  (MEM_INDEXED_BASE_CYCLES 6)
++  (MEM_EXTENDED_CYCLES 7)
++
++  ;; Cycle count for any reg-reg transfer (regardless of size)
++  (EXG_CYCLES 8)
++  (TFR_CYCLES 6)
++
++  ;; Cycle count for a condition code update (andcc/orcc)
++  (CC_CYCLES 3)
++
++  (JMP_DIRECT_CYCLES 3)
++  (JMP_INDEXED_BASE_CYCLES 3)
++  (JMP_EXTENDED_CYCLES 4)
++
++  (JSR_DIRECT_CYCLES 7)
++  (JSR_INDEXED_BASE_CYCLES 7)
++  (JSR_EXTENDED_CYCLES 8)
++
++  (LEA_BASE_CYCLES 4)
++
++  ;; Cycle count for a psh/pul operations.  Add to this the
++  ;; total number of bytes moved for the correct count.
++  (PSH_PUL_CYCLES 5)
++
++  ;; Miscellaneous cycle counts
++  (CWAI_CYCLES 20)
++  (MUL_CYCLES 11)
++  (NOP_CYCLES 2)
++  (RTI_CYCLES 15)
++  (RTS_CYCLES 5)
++  (SWI_CYCLES 20)
++  (SYNC_CYCLES 4)
++])
++
++
++;
++; An enumeration of values for each "unspec"; i.e. unspecified
++; instruction.  These represent insns that are meaningful on the
++; 6809 but which have no intrinsic meaning to GCC itself.
++; These insns can be generated explicitly using the __builtin_xxx
++; syntax; they are also implicitly generated by the backend
++; as needed to implement other insns.
++;
++(define_constants [
++  (UNSPEC_BLOCKAGE 0)
++  (UNSPEC_PUSH_RS 1)
++  (UNSPEC_POP_RS 2)
++  (UNSPEC_SWI 3)
++  (UNSPEC_CWAI 4)
++  (UNSPEC_ADD_CARRY 5)
++  (UNSPEC_SUB_CARRY 6)
++  (UNSPEC_SYNC 7)
++  (UNSPEC_ADD_DECIMAL 8)
++])
++
++
++;;--------------------------------------------------------------------
++;;-  Predicates
++;;--------------------------------------------------------------------
++
++(include "predicates.md")
++
++;;--------------------------------------------------------------------
++;;-  Attributes
++;;--------------------------------------------------------------------
++
++;;
++;; The type attribute is used to distinguish between different
++;; types of branch instructions, so that their lengths can be
++;; calculated correctly.
++;;
++(define_attr "type" "branch,cbranch,unknown" (const_string "unknown"))
++
++;;
++;; The length of a branch instruction is calculated based on how
++;; far away the branch target is.  Lengths of other insns default
++;; to 4.  set_attr is used in instruction templates to specify
++;; the length when it is known exactly.  When not sure, err on
++;; the high side to avoid compile errors.
++;;
++(define_attr "length" ""
++  (cond [
++    (eq_attr "type" "branch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_BRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_BRANCH_LENGTH)
++          (const_int SHORT_BRANCH_LENGTH)))
++    (eq_attr "type" "cbranch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_CBRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_CBRANCH_LENGTH)
++          (const_int SHORT_CBRANCH_LENGTH)))
++  ] (const_int DEFAULT_INSN_LENGTH)))
++
++
++;;
++;; The default attributes for 'asm' statements.
++;; The default length is the longest possible single 6809 instruction,
++;; which is 5 bytes.  GCC will automatically multiply this by the
++;; number of real insns contained in an asm statement.
++;;
++(define_asm_attributes
++  [(set_attr "length" "5")
++   (set_attr "type" "unknown")])
++
++;;
++;; An attribute for the number of cycles that it takes an instruction
++;; to execute.
++;;
++(define_attr "cycles" "" (const_int DEFAULT_INSN_CYCLES))
++
++
++;;--------------------------------------------------------------------
++;;- Instruction patterns.  When multiple patterns apply,
++;;- the first one in the file is chosen.
++;;-
++;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
++;;-
++;;- Note: NOTICE_UPDATE_CC in m6809.h handles condition code updates
++;;- for most instructions.
++;;--------------------------------------------------------------------
++
++;;--------------------------------------------------------------------
++;;-  Test
++;;--------------------------------------------------------------------
++
++;; cmpx is 3 bytes, not 4
++(define_insn "*tsthi_x"
++  [(set (cc0) (match_operand:HI 0 "register_operand_x" "v"))]
++  ""
++  "cmpx\t#0"
++  [(set_attr "length" "3")])
++
++;; subd #0 is 3 bytes, better than cmpd #0 which is 4 bytes
++(define_insn "*tsthi_d"
++  [(set (cc0) (match_operand:HI 0 "register_operand_d" "d"))]
++  ""
++  "subd\t#0"
++  [(set_attr "length" "3")])
++
++(define_insn "*tsthi"
++  [(set (cc0) (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "cmp%0\t#0"
++   [(set_attr "length" "4")])
++
++(define_insn "*bitqi3"
++  [(set (cc0)
++    (and:QI (match_operand:QI 0 "register_operand" "%q")
++      (match_operand:QI 1 "general_operand" "mi")))]
++  ""
++  "bit%0\t%1"
++  [(set_attr "length" "3")])
++
++
++(define_insn "tstqi"
++  [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "q,mt"))]
++  ""
++  "@
++   tst%0
++   tst\t%0"
++   [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Compare instructions
++;;--------------------------------------------------------------------
++
++;; - cmphi for register to memory or register compares
++(define_insn "cmphi"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 0 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 1 "general_operand" "mi, da,  dU")))]
++  ""
++{
++  if ((REG_P (operands[0])) && (REG_P (operands[1]))) {
++    output_asm_insn ("pshs\t%1\t;cmphi: R:%1 with R:%0", operands);
++    return "cmp%0\t,s++\t;cmphi:";
++  }
++  if (GET_CODE (operands[0]) == REG)
++    return "cmp%0\t%1\t;cmphi:";
++  else {
++    cc_status.flags |= CC_REVERSED;
++    return "cmp%1\t%0\t;cmphi:(R)";
++  }
++}
++  [(set_attr "length" "5,5,7")])
++
++
++(define_insn "cmpqi"
++  [(set (cc0)
++    (compare (match_operand:QI 0 "whole_general_operand" "q,q, q,O,mt,K")
++    (match_operand:QI 1 "whole_general_operand"          "O,mt,K,q,q, q")))]
++  ""
++{
++    if (REG_P (operands[0]) && !M_REG_P (operands[0]))
++    {
++      if (operands[1] == const0_rtx)
++        return "tst%0\t;cmpqi:(ZERO)";
++      else
++        return "cmp%0\t%1\t;cmpqi:";
++    }
++    else
++    {
++      cc_status.flags |= CC_REVERSED;
++
++      if (operands[0] == const0_rtx)
++        return "tst%1\t;cmpqi:(RZERO)";
++      else
++        return "cmp%1\t%0\t;cmpqi:(R)";
++    }
++}
++   [(set_attr "length" "1,3,2,1,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- Compare/branch pattern
++;;--------------------------------------------------------------------
++
++(define_expand "cbranchhi4"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 1 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 2 "general_operand" "mi, da,  dU")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++(define_expand "cbranchqi4"
++  [(set (cc0)
++    (compare
++      (match_operand:QI 1 "whole_general_operand" "q,q, q,O,mt,K")
++      (match_operand:QI 2 "whole_general_operand" "O,mt,K,q,q, q")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++;;--------------------------------------------------------------------
++;;-  Move
++;;--------------------------------------------------------------------
++
++; this looks good (obviously not finished) but I still see 'movsi'
++; places in udivsi3 where it's broken
++; (define_insn "pushsi1"
++;   [(set (mem:SI (pre_dec (reg:HI HARD_S_REGNUM)))
++;         (match_operand:SI 0 "general_operand" "o"))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int -4))) ]
++;   ""
++;   "; pushsi %0"
++;    [(set_attr "length" "12")])
++;
++; (define_insn "popsi1"
++;   [(set (match_operand:SI 0 "general_operand" "=o")
++;         (mem:SI (post_inc (reg:HI HARD_S_REGNUM))))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int 4))) ]
++;   ""
++;   "; popsi %0"
++;    [(set_attr "length" "12")])
++
++; (define_insn "movsi"
++;   [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
++;         (match_operand:SI 1 "general_operand"      " oi"))]
++;   ""
++;   "; movsi %0 <- %1"
++;    [(set_attr "length" "1")])
++
++; this doesn't work
++; (define_expand "movsi"
++;   [(parallel [
++;      (set (match_operand:SI 0 "nonimmediate_operand" "")
++;           (match_operand:SI 1 "general_operand" ""))
++;      (clobber (match_scratch:HI 2 ""))])]
++;   ""
++; {
++;   rtx insn;
++;   if (STACK_PUSH_P (operands[0]) || STACK_POP_P (operands[1]))
++;   {
++;     REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
++;   }
++;   insn = emit_move_multi_word (SImode, operands[0], operands[1]);
++;   DONE;
++; })
++
++
++(define_expand "movhi"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++{
++  /* One of the ops has to be in a register prior to reload */
++  if (!register_operand (operand0, HImode) &&
++      !register_operand (operand1, HImode))
++    operands[1] = copy_to_mode_reg (HImode, operand1);
++})
++
++;;; Try a splitter to handle failure cases where we try to move
++;;; an immediate constant (zero usually) directly to memory.
++;;; This absolutely requires an intermediate register.
++(define_split
++  [(set (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "immediate_operand"  ""))
++   (clobber (match_operand:HI 2 "register_operand" ""))]
++  ""
++  [(set (match_dup 2) (match_dup 1))
++   (set (match_dup 0) (match_dup 2))]
++  "")
++
++
++;;; This would be a nice method for loading from a word array,
++;;; but it is never generated because the combiner cannot merge
++;;; more than 3 instructions (there are four here).  This is
++;;; perhaps better done via a peephole.
++(define_insn "*movhi_array_load"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=da")
++    (mem:HI (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B")) (const_int 1))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;abx\;ld%0\t,x"
++   [(set_attr "length" "7")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movhi_push"
++  [(set (match_operand:HI 0 "push_operand" "=m")
++    (match_operand:HI 1 "register_operand" "U"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++(define_insn "*movhi_pic_symbolref"
++  [(set (match_operand:HI 0 "register_operand" "=a")
++    (match_operand:HI 1 "symbolic_operand" ""))]
++  "flag_pic"
++  "lea%0\t%c1,pcr"
++   [(set_attr "length" "4")])
++
++
++(define_insn "*movhi_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,d,a,ad,mu")
++    (match_operand:HI 1 "general_operand"          " a,a,d,miu,ad"))]
++  ""
++  "@
++   lea%0\t,%1
++   tfr\t%1,%0
++   tfr\t%1,%0
++   ld%0\t%1
++   st%1\t%0"
++   [(set_attr "length" "2,2,2,*,*")])
++
++
++;;; Generated by the combiner to merge an address calculation with
++;;; a byte load.  We can use the 'abx' instruction here.
++(define_insn "*movqi_array_load"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (mem:QI (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B"))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;ld%0\t,x"
++   [(set_attr "length" "6")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movqi_push"
++  [(set (match_operand:QI 0 "push_operand" "=m")
++    (match_operand:QI 1 "register_operand" " q"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++;;; Optimize the move of a byte from the stack using the puls instruction
++;;; instead of a store with post-decrement.
++(define_insn "movqi_pop"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (match_operand:QI 1 "pop_operand" "m"))]
++  ""
++  "puls\t%0"
++  [(set_attr "length" "2")])
++
++
++;;- load low byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_lsb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,m,a,d, U") 1))]
++  ""
++  "@
++   \t;movlsbqihi: D->B
++   ld%0\t%L1\t;movlsbqihi: msb:%1 -> R:%0
++   tfr\t%1,d\t;movlsbqihi: R:%1 -> R:%0
++   stb\t%0\t;movlsbqihi: R:%1 -> %0
++   pshs\t%1\t;movlsbqihi: R:%1 -> R:%0\;leas\t1,s\;puls\t%0"
++   [(set_attr "length" "0,*,2,*,6")])
++
++
++;;- load high byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_msb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,O,a,m,d, U") 0))]
++  ""
++  "@
++   tfr\ta,b\t;movmsbqihi: D->B
++   clr%0\t\t;movmsbqihi: ZERO -> R:%0
++   tfr\t%1,d\t;movmsbqihi: R:%1 -> R:%0\;tfr\ta,b
++   ld%0\t%L1\t;movmsbqihi: lsb:%1 -> R:%0
++   sta\t%0\t;movmsbqihi: R:%1 -> %0
++   pshs\t%1\t;movmsbqihi: R:%1 -> R:%0\;puls\t%0\;leas\t1,s"
++  [(set_attr "length" "2,1,4,*,*,6")])
++
++
++(define_insn "*movqi_boolean"
++  [(set (reg:QI HARD_Z_REGNUM)
++    (match_operand:QI 0 "general_operand" "q,O,i,m"))]
++  ""
++  "@
++   tst%0
++   andcc\t#~4
++   orcc\t#4
++   tst\t%0")
++
++
++(define_insn "movqi"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,m,q,m,q,z")
++    (match_operand:QI 1 "general_operand"          " q,O,O,mi,q,z,q"))]
++  ""
++  "@
++   tfr\t%1,%0
++   clr%0
++   clr\t%0
++   ld%0\t%1
++   st%1\t%0
++   tfr\tcc,%0\;and%0\t#4
++   tst%0"
++   [(set_attr "length" "2,1,3,*,*,4,1")])
++
++
++;;--------------------------------------------------------------------
++;;-  Swap registers
++;;--------------------------------------------------------------------
++
++; Note: 8-bit swap is never needed so it is not defined.
++
++(define_insn "swaphi"
++  [(set (match_operand:HI 0 "register_operand" "+r")
++    (match_operand:HI 1 "register_operand" "+r"))
++   (set (match_dup 1) (match_dup 0))]
++  ""
++  "exg\t%1,%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int EXG_CYCLES))])
++
++
++(define_insn "bswaphi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
++  ""
++  "exg\ta,b"
++  [(set_attr "length" "2")])
++
++
++;;--------------------------------------------------------------------
++;;-  Extension and truncation insns.
++;;--------------------------------------------------------------------
++
++(define_insn "extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (sign_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "sex\t\t;extendqihi2: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++(define_insn "zero_extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (zero_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "clra\t\t;zero_extendqihi: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++;;--------------------------------------------------------------------
++;;- All kinds of add instructions.
++;;--------------------------------------------------------------------
++
++
++;;
++;; gcc's automatic version of addsi3 doesn't know about adcb,adca
++;; so it is MUCH less efficient.  Define this one ourselves.
++;;
++;; TODO - can't always get 'd' for the clobber... allow other registers
++;; as well and use exg d,R ... exg R,d around the code sequence to
++;; use others, at a price.  Also consider libcall for this when
++;; optimizing for size.
++;;
++(define_insn "addsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (plus:SI (match_operand:SI 1 "general_operand" "%o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (PLUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++; Increment of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int 1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("inc\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("inc\t%0\;__IL%=:", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Decrement of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_minus1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int -1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("tst\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("dec\t%0", xoperands);
++  output_asm_insn ("__IL%=:", xoperands);
++  output_asm_insn ("dec\t%1", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Allow the addition of an 8-bit quantity to a 16-bit quantity
++; using the LEAX B,Y addressing mode, where X and Y are both
++; index registers.  This will only get generated via the peephole
++; which removes a sign extension.
++(define_insn "*addhi_b"
++  [(set (match_operand:HI 0 "index_register_operand"       "=a")
++    (plus:HI(match_operand:HI 1 "index_register_operand"   "%a")
++    (match_operand:QI 2 "register_operand"                  "q")
++  ))]
++  ""
++  "lea%0\t%2,%1\t;addhi_b: R:%0 = R:%2 + R:%1"
++  [(set_attr "length" "*")])
++
++
++; Splitter for addhi pattern #5 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "memory_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   (set (reg:HI HARD_D_REGNUM)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 1)))
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   ]
++{
++})
++
++
++; Splitter for addhi pattern #7 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   (set (match_dup 0)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 0)))
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   ]
++{
++})
++
++
++; TODO - this is ugly.  During RTL generation, we don't know what registers
++; are available, so the multiple-insn sequences can only be solved
++; via 'define_split's during matching.  See andhi3 for an example.
++; Keep the constraints with ? modifiers to help reload pick the right
++; registers.
++;
++; The forms are:
++; 1. D += D, expand this into a shift instead. (rtx costs should be corrected
++; to avoid this even happening...)
++; 2. D += U, require U to be pushed to memory.  (Lots of patterns do this
++; now, is this a better way?)
++; 3. Best choice: 'addd'
++; 4. Next best choice: 'lea'
++; 5. Hybrid of 3 and 4
++; 6. Same as 4, not bad
++; 7. BAD, no D register at all
++; 8. 'lea', as good as 4.
++(define_insn "addhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"      "=d, d,  d,  a,?a, a,???T,a")
++    (plus:HI(match_operand:HI 1 "add_general_operand"   "%0, 0,  0,  d, 0, a, 0, a")
++    (match_operand:HI 2 "general_operand"               " 0, !U, mi, a, m, d, T, i")
++  ))]
++  ""
++  "@
++   lslb\t\t;addhi: R:%0 += R:%2\;rola\t\t;also R:%0 *= 2
++   pshs\t%2\t;addhi: R:%0 += R:%2\;add%0\t,s++
++   add%0\t%2
++   lea%0\t%1,%2
++   #
++   lea%0\t%2,%1
++   #
++   lea%0\t%a2,%1"
++   [(set_attr "length" "2,6,*,*,7,*,7,*")])
++
++
++(define_insn "addqi3_carry"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_ADD_CARRY))]
++  ""
++  "adc%0\t%2\t;addqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++; TODO: specifying 'A' for the first constraint, to force into the A register
++; is not working because of the way registers are currently set up.  This will
++; take some work to get right.  Thus the second alternative as a backup.
++(define_insn "addqi3_decimal"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=A,?q")
++    (unspec:QI [
++      (match_operand:QI 1 "general_operand"        "%0,0")
++      (match_operand:QI 2 "general_operand"        "mi,mi")] UNSPEC_ADD_DECIMAL))]
++  ""
++  "@
++   adda\t%2\;daa
++   tfr\t%0,a\;adda\t%2\;daa\;tfr\ta,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "addqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "=q,q,q,m,m,q")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "%0,0,0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " 0,I,N,I,N,mi")))]
++  ""
++  "@
++   asl%0\t\t;addqi: R:%0 = R:%0 + R:%0
++   inc%0
++   dec%0
++   inc\t%0
++   dec\t%0
++   add%0\t%2"
++  [(set_attr "length" "1,1,1,3,3,*")])
++
++
++;;--------------------------------------------------------------------
++;;- Subtract instructions.
++;;--------------------------------------------------------------------
++
++(define_insn "subsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (minus:SI (match_operand:SI 1 "general_operand" " o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (MINUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++(define_insn "subhi3"
++  [(set (match_operand:HI 0 "register_operand"      "=d,  d, a")
++    (minus:HI (match_operand:HI 1 "register_operand" "0,  0, 0")
++    (match_operand:HI 2 "general_operand"            "mi, ?U,n")))]
++  ""
++  "@
++   sub%0\t%2\t;subhi: R:%0 -= %2
++   pshs\t%2\t;subhi: R:%0 -= R:%2\;sub%0\t,s++
++   lea%0\t%n2,%1\t;subhi: R:%0 = R:%1 + %n2"
++   [(set_attr "length" "*,5,3")])
++
++
++(define_insn "subqi3_carry"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_SUB_CARRY))]
++  ""
++  "sbc%0\t%2\t;subqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++(define_insn "subqi3"
++  [(set (match_operand:QI 0 "register_operand"            "=q, q, !q, q")
++    (minus:QI (match_operand:QI 1 "whole_register_operand" "0, 0,  I, 0")
++    (match_operand:QI 2 "whole_general_operand"            "I, mi, 0, t")))]
++  ""
++  "@
++   dec%0
++   sub%0\t%2
++   dec%0\;neg%0
++   sub%0\t%2"
++   [(set_attr "length" "1,3,2,3")])
++
++
++;;--------------------------------------------------------------------
++;;- Multiply instructions.
++;;--------------------------------------------------------------------
++
++; TODO - merge these two instructions, using 'extend_operator' to match
++; either signed or zero extension.  Everything else is the same.
++(define_insn "mulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++      (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++      (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;mulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++(define_insn "umulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++    (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++    (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;umulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++; Expand a 16x16 multiplication into either a libcall or a shift.
++; If the second operand is a small constant, use the above form.
++; Otherwise, do a libcall.
++(define_expand "mulhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (mult:HI (match_operand:HI 1 "general_operand" "")
++    (match_operand:HI 2 "nonmemory_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "mulhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- Divide instructions.
++;;--------------------------------------------------------------------
++
++(define_expand "divhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (div:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "divhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "divqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (div:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "divqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "udivhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++     (udiv:HI (match_operand:HI 1 "register_operand" "")
++              (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "udivhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- mod
++;;--------------------------------------------------------------------
++
++(define_expand "modhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (mod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "modhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "modqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (mod:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "modqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "umodhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (umod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "umodhi3", operands, 2);
++  DONE;
++})
++
++
++
++;;--------------------------------------------------------------------
++;;- and, or, xor common patterns
++;;--------------------------------------------------------------------
++
++; Split a bitwise HImode into two QImode instructions, with one of
++; the sources in a pushable register.  The register is pushed onto
++; the stack and memory pop operands (,s+) are used in the QI forms.
++(define_split
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "register_operand" "")]))]
++  "reload_completed"
++  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 2))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++})
++
++; Split a bitwise HImode into two QImode instructions, with one
++; of the sources being a (MEM (MEM (...)); i.e. an indirect memory
++; reference.  This requires dereferencing the pointer into a
++; temporary register (X), which must be saved/restored around the
++; compute instructions.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (mem:HI (match_operand:HI 2 "memory_operand" ""))]))]
++  "reload_completed"
++  [
++   (set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 4))
++   (set (match_dup 4) (match_dup 2))
++   (set (match_dup 4) (mem:HI (match_dup 4)))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (match_dup 4) (mem:HI (post_inc:HI (reg:HI HARD_S_REGNUM))))
++   ]
++{
++  /* Use X for a temporary index register */
++  operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
++})
++
++
++; Split a bitwise HImode into two QImode instructions.  This is
++; the common case.  This handles splitting when neither of the
++; above two cases applies.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "general_operand" "")]))]
++  "reload_completed"
++  [(set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_A_REGNUM) (match_dup 4)]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_D_REGNUM) (match_dup 5)]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[4] = gen_rtx_const_high (operands[2]);
++    operands[5] = gen_rtx_const_low (operands[2]);
++  }
++  else if ((GET_CODE (operands[2]) == MEM)
++    && (GET_CODE (XEXP (operands[2], 0)) == MEM))
++  {
++    FAIL;
++  }
++  else
++  {
++    operands[4] = gen_highpart (QImode, operands[2]);
++    operands[5] = gen_lowpart (QImode, operands[2]);
++  }
++})
++
++; Below are the specific cases for each of the operators.
++; The QImode versions are the simplest and can be implemented
++; directly on the hardware.  The HImode cases are all output
++; using one of the above splitting techniques.
++
++;;--------------------------------------------------------------------
++;;- and
++;;--------------------------------------------------------------------
++
++(define_insn "andhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (and:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++;; it is not clear that this is correct
++(define_insn "*andqi_2"
++  [(set
++   (match_operand:QI 0 "register_operand" "=q")
++   (and:QI (match_operand:QI 1 "register_operand" "q")
++     (match_operand 2 "const_int_operand" "i")))]
++  ""
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[3] = GEN_INT(INTVAL(operands[2]) & 0xff);
++    return "and%0 %3";
++  }
++
++  return "and%0 %2";
++}
++  [(set_attr "length" "2")])
++
++(define_insn "andqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,qc")
++    (and:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   clr%0\t;andqi(ZERO)
++   \t;andqi(-1)
++   and%0\t%2
++   and%0\t%2"
++   [(set_attr "length" "1,0,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- or
++;;--------------------------------------------------------------------
++
++(define_insn "iorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (ior:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "iorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q, qc")
++    (ior:QI (match_operand:QI 1 "whole_register_operand" "%0,0, 0")
++    (match_operand:QI 2 "whole_general_operand"          " O,m,i")))]
++  ""
++  "@
++   \t;iorqi(ZERO)
++   or%0\t%2
++   or%0\t%2"
++   [(set_attr "length" "0,3,2")])
++
++;;--------------------------------------------------------------------
++;;- xor
++;;--------------------------------------------------------------------
++
++(define_insn "xorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (xor:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "xorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,q")
++    (xor:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   \t;xorqi(ZERO)
++   com%0\t;xorqi(-1)
++   eor%0\t%2
++   eor%0\t%2"
++   [(set_attr "length" "0,1,3,2")])
++
++;;--------------------------------------------------------------------
++;;-  Two's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "neghi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!a")
++    (neg:HI (match_operand:HI 1 "general_operand"   "0, 0")))]
++  ""
++  "@
++   nega\;negb\;sbca\t#0
++   exg\td,%0\;nega\;negb\;sbca\t#0\;exg\td,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "negqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   neg%0
++   neg\t%0"
++  [(set_attr "length" "1,3")])
++
++
++;;--------------------------------------------------------------------
++;;-  One's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "one_cmplhi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,?tm,???a")
++    (not:HI (match_operand:HI 1 "general_operand"   "0,  0,   0")))]
++  ""
++  "@
++   coma\;comb
++   com\t%0\;com\t%L0
++   exg\td,%0\;coma\;comb\;exg\td,%0"
++  [(set_attr "length" "2,6,6")])
++
++
++(define_insn "one_cmplqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   com%0
++   com\t%0"
++  [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Shifts/rotates
++;;--------------------------------------------------------------------
++
++(define_code_iterator bit_code [ashift ashiftrt lshiftrt])
++(define_code_attr bit_code_name [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
++
++(define_mode_iterator bit_mode [QI HI])
++(define_mode_attr bit_mode_name [(QI "qi3") (HI "hi3")])
++
++;; Emit RTL for any shift (handles all 3 opcodes and 2 mode sizes)
++
++(define_expand "<bit_code:bit_code_name><bit_mode:bit_mode_name>"
++  [(set (match_operand:bit_mode 0 "nonimmediate_operand" "")
++    (bit_code:bit_mode (match_operand:bit_mode 1 "general_operand" "")
++    (match_operand:bit_mode 2 "nonmemory_operand" "")))]
++  ""
++{
++})
++
++; Individual instructions implemented in the CPU.
++
++
++(define_insn "*ashift1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashift:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asl\t%0
++   asl%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*lshiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   lsr\t%0
++   lsr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*ashiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asr\t%0
++   asr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*rotate1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotate:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   rol\t%0
++   rol%0"
++  [(set_attr "length" "3,1")])
++
++
++(define_insn "*rotatert1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotatert:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   ror\t%0
++   ror%0"
++  [(set_attr "length" "3,1")])
++
++
++; A shift by 8 for D reg can be optimized by just moving
++; between the A/B halves, and then zero/sign extending or
++; filling in zeroes.
++; Because GCC does not understand that 'A' and 'D' refer to
++; the same storage location, we must use 'USE' throughout
++; to prevent deletion of 'unnecessary' instructions.
++; Similar optimization for MEM would require a scratch register
++; so is not done here.
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_A_REGNUM) (reg:QI HARD_D_REGNUM))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (const_int 0))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (lshiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (zero_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++
++; On the WPC hardware, there is a shift register that can be used
++; to compute (1<<n) efficiently in two instructions.  Note that this
++; form only works when using -mint8 though, because C will promote
++; to 'int' when doing this operation.  TODO : we need a 16-bit form too.
++(define_insn "ashlqi3_wpc"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (ashift:QI (match_operand:QI 1 "immediate_operand" "I")
++    (match_operand:QI 2 "general_operand" "q")))]
++  "TARGET_WPC"
++  "st%2\t0x3FF7\;ld%0\t0x3FF7"
++  [(set_attr "length" "6")])
++
++
++; Internal instructions for shifting by a constant.
++; Two forms are provided, one for QImode, one for HImode.
++; These are always split into the above instructions
++; (except for QImode forms that directly match one of the
++; above instructions, in which the condition will not
++; allow the splitter to match).
++
++(define_insn_and_split "<bit_code:bit_code_name>hi3_const"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=dm")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "immediate_operand"            "n")))]
++  ""
++  "#"
++  "reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++
++(define_insn_and_split "<bit_code:bit_code_name>qi3_const"
++  [(set (match_operand:QI 0 "nonimmediate_operand"     "=qm")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "immediate_operand"            "n")))]
++  "INTVAL (operands[2]) > 1"
++  "#"
++  "&& reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++; Internal instructions for shifting by a nonconstant.
++; These expand into complex assembly.
++
++(define_insn "<bit_code:bit_code_name>hi3_reg"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=d")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "20")])
++
++
++(define_insn "<bit_code:bit_code_name>qi3_reg"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "16")])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Jumps and transfers
++;;--------------------------------------------------------------------
++
++;;; The casesi pattern is normally *not* defined; see 'tablejump' instead.
++(define_expand "casesi"
++  [(match_operand:HI 0 "register_operand" "")   ; index to jump on
++   (match_operand:HI 1 "immediate_operand" "")   ; lower bound
++   (match_operand:HI 2 "immediate_operand" "")   ; total range
++   (match_operand 3 "" "")   ; table label
++   (match_operand 4 "" "")]  ; out of range label
++  "TARGET_BYTE_INT && TARGET_CASESI"
++{
++  m6809_do_casesi (operands[0], operands[1], operands[2],
++                   operands[3], operands[4]);
++  DONE;
++})
++
++(define_insn "tablejump_short_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (zero_extend:HI (match_operand:QI 0 "register_operand" "q")))))]
++  ""
++  "jmp\t[b,x]\t;tablejump_short_offset"
++  [(set_attr "length" "3")])
++
++(define_insn "tablejump_long_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (match_operand:HI 0 "register_operand" "d"))))]
++  ""
++  "jmp\t[d,x]\t;tablejump_long_offset"
++  [(set_attr "length" "3")])
++
++
++ ;; A tablejump operation gives the address in operand 0, with the
++ ;; CODE_LABEL for the table in operand 1.  The 'define_expand'
++ ;; shows the arguments as GCC presents them.  For a register
++ ;; operand, the assembly code is straightforward.  For a MEM,
++ ;; assumed to be a SYMBOL_REF, two forms are given, one normal
++ ;; and one for PIC mode.
++ (define_expand "tablejump"
++    [(parallel [
++     (set (pc) (match_operand:HI 0 "" ""))
++     (use (label_ref (match_operand 1 "" "")))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++    ""
++ {
++ })
++
++
++(define_insn "*tablejump_reg"
++   [(parallel [
++      (set (pc)
++         (match_operand:HI 0 "register_operand" "a"))
++      (use (label_ref (match_operand 1 "" "")))
++      (clobber (match_scratch:HI 2 ""))
++      ])]
++   ""
++   "jmp\t,%0"
++   [(set_attr "length" "3")])
++
++
++(define_insn "*tablejump_symbol"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "a")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++  "!flag_pic"
++{
++  output_asm_insn ("jmp\t[%a1,%0]", operands);
++  return "";
++}
++  [(set_attr "length" "4")])
++
++
++(define_insn "*tablejump_symbol_pic"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "d")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 "=&a"))
++     ])]
++  "flag_pic"
++{
++  output_asm_insn ("lea%2\t%a1,pcr", operands);
++  output_asm_insn ("ld%0\t%0,%2", operands);
++  output_asm_insn ("jmp\t%0,%2", operands);
++  return "";
++}
++  [(set_attr "length" "8")])
++
++
++(define_insn "indirect_jump"
++  [(set (pc)
++    (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "jmp\t,%0"
++  [(set_attr "length" "3")])
++
++
++(define_insn "jump"
++  [(set (pc) (label_ref (match_operand 0 "" "")))]
++  ""
++{
++  return output_branch_insn ( LABEL_REF, operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "branch"))])
++
++; Output assembly for a condition branch instruction.
++(define_insn "*cond_branch"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 0 "" "")) (pc)))]
++  ""
++{
++  return output_branch_insn ( GET_CODE(operands[1]),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++; Similar to above, but for a condition branch instruction that
++; had its operands reversed at some point.
++(define_insn "*cond_branch_reverse"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++      (pc) (label_ref (match_operand 0 "" ""))))]
++  ""
++{
++  return output_branch_insn ( reverse_condition (GET_CODE(operands[1])),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Calls
++;;--------------------------------------------------------------------
++
++;; Generate a call instruction for a function that does not
++;; return a value.  The expander is used during RTL generation.
++;; The instructions below are used during matching; only one
++;; of them will be used, depending on the type of function
++;; being called.  The different conditions are:
++;;
++;;    1) far_functionp - is this a far function?  Those need
++;;    to be output as indirect calls through a far-function
++;;    handler.
++;;
++;;    2) noreturn_functionp - if the function does not return,
++;;    we can use a 'jmp' instead of a 'jsr' to call it.
++;;
++;;    3) is PIC mode enabled?  If so, we'll always use
++;;    relative calls (lbsr or lbra).
++;;
++;; Note: not all combinations are fully supported, especially
++;; relating to PIC.
++;;
++;; The 'bsr' instruction is never generated.
++
++(define_expand "call"
++  [(call (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*call_nopic_far"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "far_functionp (operands[0])"
++{
++  output_far_call_insn (operands, 0);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++; PIC forms come first, and should only match
++; (MEM (SYMBOL_REF)).  Other MEM forms are treated as usual.
++(define_insn "*call_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && !noreturn_functionp (operands[0])"
++  "lbsr\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "!noreturn_functionp (operands[0])"
++  "jsr\t%0"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++(define_insn "*call_noreturn_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && noreturn_functionp (operands[0])"
++  "lbra\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_noreturn_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "noreturn_functionp (operands[0])"
++  "jmp\t%0"
++  [(set_attr "length" "3")])
++
++
++;;
++;; Same as above, but for functions that do return a value.
++;;
++(define_expand "call_value"
++  [(set (match_operand 0 "" "")
++    (call (match_operand:HI 1 "memory_operand" "")
++    (match_operand:HI 2 "general_operand" "")))]
++  ""
++  "")
++
++
++(define_insn "*call_value_far"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  "far_functionp (operands[1])"
++{
++  output_far_call_insn (operands, 1);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++(define_insn "*call_value_pic"
++  [(set (match_operand 0 "" "=gz")
++    (call (mem:HI (match_operand:HI 1 "symbolic_operand" ""))
++    (match_operand:HI 2 "general_operand" "g")))]
++  "flag_pic"
++  "lbsr\t%C1"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_value_nopic"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  ""
++  "jsr\t%1"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++
++;;
++;; How to generate an untyped call.
++;;
++(define_expand "untyped_call"
++  [(parallel [(call (match_operand 0 "" "")
++        (const_int 0))
++      (match_operand 1 "" "")
++      (match_operand 2 "" "")])]
++  ""
++{
++  int i;
++
++  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
++  for (i=0; i < XVECLEN (operands[2], 0); i++)
++  {
++    rtx set = XVECEXP (operands[2], 0, i);
++    emit_move_insn (SET_DEST (set), SET_SRC (set));
++  }
++  emit_insn (gen_blockage ());
++  DONE;
++})
++
++
++(define_expand "sibcall"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "")
++            (match_operand:HI 1 "immediate_operand" ""))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_1"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "m")
++            (match_operand:HI 1 "immediate_operand" "i"))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%0"
++  [(set_attr "length" "4")])
++
++
++(define_expand "sibcall_value"
++  [(parallel
++     [(set (match_operand 0 "" "")
++         (call (match_operand:HI 1 "memory_operand" "")
++               (match_operand:HI 2 "immediate_operand" "")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_value_1"
++  [(parallel
++     [(set (match_operand 0 "" "=gz")
++         (call (match_operand:HI 1 "memory_operand" "m")
++               (match_operand:HI 2 "immediate_operand" "i")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%1"
++  [(set_attr "length" "4")])
++
++
++;;--------------------------------------------------------------------
++;;-  Function Entry and Exit
++;;--------------------------------------------------------------------
++
++;; On entry to a function, the stack frame looks as follows:
++;; - return address (pushed by the caller)
++;; - saved registers
++;; - local variable storage
++;;
++;; If the function does not modify the stack after that, then
++;; any of these can be accessed directly as an offset from
++;; STACK_POINTER_REGNUM.  Otherwise, a frame pointer is required.
++;; In that case, the prologue must also initialize HARD_FRAME_POINTER_REGNUM
++;; and all references to the stack frame will use that as a base instead.
++;;
++(define_expand "prologue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_prologue_insns ();
++  DONE;
++})
++
++
++;; The function epilogue does exactly the reverse of the prologue,
++;; deallocating local variable space, restoring saved registers,
++;; and returning.
++;;
++;; For the 6809, the return may be 'rti' if the function was
++;; declared as an interrupt function, but is normally 'rts'.
++;;
++;; Also, as an optimization, the register restore and the 'rts'
++;; can be combined into a single instruction, by adding 'PC' to the
++;; list of registers to be restored.  This is only done if there are
++;; any saved registers, as 'rts' is more efficient by itself.
++;;
++(define_expand "epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (false);
++  DONE;
++})
++
++
++(define_expand "sibcall_epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (true);
++  DONE;
++})
++
++
++;; The RTS instruction
++(define_insn "return_rts"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () == 0"
++  "rts"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++(define_insn "return_puls_pc"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () != 0"
++  ""
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++;; The RTI instruction
++(define_insn "return_rti"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "m6809_current_function_has_type_attr_p (\"interrupt\")"
++  "rti"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTI_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;-  Unspecified instructions
++;;--------------------------------------------------------------------
++
++;; An instruction that has the effect of an unspec_volatile, but
++;; which doesn't require emitting any assembly code.
++(define_insn "blockage"
++  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
++  ""
++  ""
++  [(set_attr "length" "0")
++   (set (attr "cycles") (const_int 0))])
++
++
++;; Say how to push multiple registers onto the stack, using
++;; the 6809 'pshs' instruction.  The operand is a regset
++;; specifying which registers to push.
++;;
++;; The operand mode is not given intentionally, so as to allow
++;; any possible integer mode for the regset.
++;;
++;; See below for a peephole that can combine consecutive push
++;; instructions that qualify for merging.
++(define_insn "register_push"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "pshs\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++;; Say how to pop multiple registers from the stack, using
++;; the 6809 'puls' instruction.  The operand is the register
++;; bitset value.
++(define_insn "register_pop"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_POP_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "puls\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++(define_insn "m6809_swi"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "I,n")] UNSPEC_SWI)]
++  ""
++  "@
++   swi
++   swi%c0"
++  [(set_attr "length" "1,2")
++   (set (attr "cycles") (const_int SWI_CYCLES))])
++
++
++;; Generate the CWAI instruction
++(define_insn "m6809_cwai"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "")] UNSPEC_CWAI)]
++  ""
++  "cwai\t%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int CWAI_CYCLES))])
++
++
++;; Generate the SYNC instruction
++(define_insn "m6809_sync"
++  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
++  ""
++  "sync"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int SYNC_CYCLES))])
++
++
++;; Generate the NOP instruction
++(define_insn "nop"
++  [(const_int 0)]
++  ""
++  "nop"
++   [(set_attr "length" "1")
++   (set (attr "cycles") (const_int NOP_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;- Peepholes
++;;--------------------------------------------------------------------
++
++;;; Each peephole has an ID that is used for debugging.
++;;; Each peephole condition is bracketed by calls to
++;;; m6809_match_peephole2() also for debugging.
++(define_constants [
++  (PEEP_END 0)
++  (PEEP_COND 1)
++
++  (PEEP_STACK_STORE_INC 0)
++  (PEEP_STACK_CLEAR_INC 1)
++  (PEEP_LSRB_ADCB 2)
++  (PEEP_ABX 3)
++  (PEEP_ABX2 4)
++  (PEEP_INDEXED_INC 5)
++  (PEEP_MEM_DEC 6)
++  (PEEP_MEM_INC 7)
++  (PEEP_MEM_DEC_CMP 8)
++  (PEEP_PUSH2 9)
++  (PEEP_STORE_IMPLIES_CC 10)
++  (PEEP_DEC_IMPLIES_CC 11)
++  (PEEP_LEAB 12)
++  (PEEP_LDX_INDIRECT 13)
++  (PEEP_POP_JUNK 14)
++])
++
++
++;;; Optimize 'leas -1,s' followed by 'stb ,s'.  This can happen if the
++;;; function prologue needs to allocate stack space and 'b' is placed
++;;; into that local right away.  Combine the stack allocation with the
++;;; store using preincrement mode.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM)
++        (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM))
++        (match_operand:QI 0 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_STACK_STORE_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 0))]
++  "")
++
++
++;;; Same as above, but for a 'clr ,s' that follows the prologue.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM) (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM)) (const_int 0))]
++  "m6809_match_peephole2 (PEEP_STACK_CLEAR_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (const_int 0))]
++  "")
++
++
++;;; Merge two consecutive push instructions into a single register_push.
++(define_peephole2
++  [(set (match_operand 0 "push_operand" "")
++    (match_operand 1 "register_operand" ""))
++   (set (match_operand 2 "push_operand" "")
++    (match_operand 3 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_PUSH2, PEEP_COND)
++   && reload_completed
++   && GET_MODE (operands[1]) == GET_MODE (operands[3])
++   && m6809_can_merge_pushpop_p (UNSPEC_PUSH_RS, 1 << REGNO (operands[1]), 1 << REGNO (operands[3]))
++   && m6809_match_peephole2 (PEEP_PUSH2, PEEP_END)"
++  [(parallel [
++    (use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile [(match_dup 4)] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))])
++   (use (match_dup 1))
++   (use (match_dup 3))]
++{
++  operands[4] = gen_rtx_CONST_INT (QImode,
++    (1 << REGNO (operands[1])) | (1 << REGNO (operands[3])));
++})
++
++
++;;; Convert 'stX ,--s' into a push instruction.  Use the regset
++;;; notation, so that it may be combined with an adjacent regset.
++;;; TBD - this doesn't compile some code cleanly.
++;(define_peephole2
++;  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM)))
++;        (reg:HI HARD_X_REGNUM))]
++;  "reload_completed"
++;  [(parallel [
++;    (use (reg:HI HARD_S_REGNUM))
++;    (unspec_volatile [(match_dup 0)] UNSPEC_PUSH_RS)
++;    (clobber (reg:HI HARD_S_REGNUM))])]
++;{
++;  operands[0] = gen_rtx_CONST_INT (HImode, X_REGBIT);
++;})
++
++
++;;;
++;;; q = (q+1)/2 can be optimized as "lsrb; adcb".  This also
++;;; won't overflow when q=0xFF.
++;;; TODO : this form isn't accounting for promotion when
++;;; using 16-bit ints.
++;;;
++(define_peephole
++  [(set (reg:QI HARD_D_REGNUM)
++    (lshiftrt:QI (plus:HI (match_dup 0) (const_int 1)) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_LSRB_ADCB, PEEP_END)"
++  "lsrb\;adcb\t#0; peephole"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Optimize the case of following a register store with a test
++;; of reg or mem just moved.
++;;
++(define_peephole
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++  (match_operand:HI 1 "register_operand" "r"))
++   (set (cc0) (match_operand:HI 2 "general_operand" "g"))]
++  "m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_COND)
++   && (operands[2] == operands[0] || operands[2] == operands[1])
++   && m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_END)"
++  "st%1\t%0\t;movhi: R:%1 -> %0 w/ implied test of %2"
++  [(set_attr "length" "4")])
++
++
++;; Optimize a pair of SET instructions in which the second insn
++;; is the reverse of the first one.  I.e.
++;;
++;; A = B
++;;        ---->  A = B
++;; B = A
++;;
++;; The second insn is redundant.  Define two patterns, one for QI, one for HI.
++;; But don't do this if either is a VOLATILE MEM.
++(define_peephole2
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++        (match_operand:HI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;
++;; Optimize the sum of an 8-bit and 16-bit using the 'abx' instruction
++;; if B and X can be used.  Two patterns are provided to catch both
++;; X=X+D and X=D+X.
++;;
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++;;; Likewise, handle when B is scaled by 2 prior to the add.
++;;; Instead of shifting B in 4 cycles, just do the ABX a second
++;;; time, in only 3 cycles.
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Work around a compiler bug that generates bad code when copying
++;; between 32-bit memory addresses after a libcall.  The problem seen is
++;; that the source is MEM (REG X), but X is used as the reload register.
++;; The second half of the copy therefore fails.
++;;
++;; The solution is to switch the reload register to D, since that is guaranteed
++;; not to be in use right after a libcall.
++;;
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_operand:HI 0 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_operand:HI 1 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))]
++  "reload_completed"
++  [(set (reg:HI HARD_D_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_dup 0) (reg:HI HARD_D_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_dup 1) (reg:HI HARD_X_REGNUM))]
++  "")
++
++
++;; Turn "and then test" into a "bit test" operation.
++;; Provide variants for immediate and memory sources
++;; This is the most used peephople.
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "immediate_operand" "i")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "3")])
++; 
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "memory_operand" "m")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "4")])
++
++
++;; Turn a "decrement, then test" sequence into just a "decrement".
++;; The test can be omitted, since it is implicitly done.
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "")
++    (match_operand:QI 2 "immediate_operand" "")))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_DEC_IMPLIES_CC, PEEP_END)"
++  [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))]
++  "")
++
++
++;; Merge an indexed register increment with a previous usage.
++;; This is usually done automatically, but not always
++;; The 'use' should be optional; in all cases where this has been
++;; seen, it is required though.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++     (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (use (match_dup 0))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_INDEXED_INC, PEEP_END)"
++  [(set (match_dup 0) (mem:QI (post_inc:HI (match_dup 1))))
++   (use (match_dup 0))]
++  "")
++
++
++;;; Merge "ldX MEM; ldX ,X" into a single instruction using
++;;; the indirect mode.
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (match_operand:HI 0 "general_operand" "")))
++   (set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LDX_INDIRECT, PEEP_END)"
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (mem:HI (match_dup 0))))]
++  "")
++
++
++;;; Reorder a store followed by a unary operation on that memory
++;;; so that the unary is performed and then the store.  Consider
++;;; a binary shift operation, which will be decomposed into
++;;; identical single shifts, also.
++;;; TODO - recognize more than just 'ashift' here.
++(define_peephole2
++  [(set (match_operand:QI 0 "memory_operand" "")
++        (match_operand:QI 1 "register_operand" ""))
++   (set (match_dup 0)
++        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++  "reload_completed"
++  [(set (match_dup 1)
++        (ashift:QI (match_dup 1) (match_operand:QI 2 "immediate_operand")))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++;;; Likewise, reorder a unary MEM followed by a load, so that the load
++;;; is done first, then use the REG instead of the MEM.
++;;;(define_peephole2
++;;;  [(set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))
++;;;   (set (match_operand:QI 0 "register_operand" "")
++;;;        (match_operand:QI 1 "memory_operand" ""))]
++;;;  "reload_completed"
++;;;  [(set (match_dup 0) (match_dup 1))
++;;;   (set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++;;;  "")
++
++
++;;; Replace sex; leaX d,Y with leaX b,Y.
++;;;
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (match_operand:HI 1 "index_register_operand" "")
++                 (reg:HI HARD_D_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (reg:HI HARD_D_REGNUM)
++          (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++
++;;; Replace ldb; decb; stb; tstb with dec(mem).  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC_CMP, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace ldb; decb; stb with dec(mem); ldb.  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_INC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;; Replace "andb #N; cmpb #N; bhi" with "andb #N", if it can be proven
++;;; that the branch can never occur because of the limited range of B.
++;;; N must be a power of two for this to make sense.  This helps with
++;;; the default cases of switch statements on a value (x & N).
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++    (and:QI (match_dup 0) (match_operand:QI 1 "immediate_operand" "")))
++   (set (cc0)
++    (compare (match_dup 0) (match_dup 1)))
++   (set (pc) (if_then_else (gtu (cc0) (const_int 0)) (match_operand 2 "" "") (match_operand 3 "" "")))
++   ]
++  "reload_completed && power_of_two_p (INTVAL (operands[1]) + 1)"
++  [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
++  "")
++
++;;; Replace ldd <mem>; addd #1; std <mem> with 16-bit increment
++;;; of the mem, but only if D is dead.  Same for 16-bit decrement.
++;;; <mem> must be offsettable for the instruction to match.
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace a load or store using an indexed register, followed by an increment of that
++;;; register, with the combined form using autoincrement.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++   "reload_completed"
++  [(set (match_dup 0) (mem:QI (post_inc (match_dup 1))))]
++  "")
++
++
++;;- mode:emacs-lisp
++;;- comment-start: ";;- "
++;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
++;;- eval: (modify-syntax-entry ?[ "(]")
++;;- eval: (modify-syntax-entry ?] ")[")
++;;- eval: (modify-syntax-entry ?{ "(}")
++;;- eval: (modify-syntax-entry ?} "){")
++;-; vim: set ts=2:
++;-; vim: set expandtab:
++;-; vim: set filetype=lisp:
++;;- End:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.opt gcc-4.6.4/gcc/config/m6809/m6809.opt
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.opt	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.opt	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,98 @@
++; Options for the M6809 port of the compiler
++;
++; Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
++; 02110-1301, USA.
++
++margcount
++Target Mask(ARGCOUNT)
++Push argument count
++
++mint8
++Target RejectNegative Mask(BYTE_INT)
++Use 8-bit integers
++
++mint16
++Target RejectNegative
++Use 16-bit integers InverseMask(BYTE_INT)
++
++mreg-args
++Target Mask(REG_ARGS)
++Use registers for function arguments
++
++mshort_size 
++Target RejectNegative Mask(SMALL_SIZE_T)
++Use 8-bit size_t
++
++mlong_size
++Target RejectNegative InverseMask(SMALL_SIZE_T)
++Use 16-bit size_t
++
++mdirect
++Target Mask(DIRECT)
++Enable direct addressing
++
++mwpc
++Target RejectNegative Mask(WPC)
++Enable WPC platform extensions
++
++mexperiment
++Target RejectNegative Mask(EXPERIMENT)
++Enable current experimental feature
++
++m6309
++Target RejectNegative Mask(6309)
++Enable Hitachi 6309 extensions
++
++mcasesi
++Target RejectNegative Mask(CASESI)
++Enable the casesi pattern
++
++mfar-code-page=
++Target RejectNegative Joined Var(far_code_page_option)
++Sets the far code page value for this compilation unit
++
++mcode-section=
++Target RejectNegative Joined Var(code_section_ptr)
++Sets the name of the section for code
++
++mdata-section=
++Target RejectNegative Joined Var(data_section_ptr)
++Sets the name of the section for initialized data
++
++mbss-section=
++Target RejectNegative Joined Var(bss_section_ptr)
++Sets the name of the section for uninitialized data
++
++mabi_version=
++Target RejectNegative Joined Var(m6809_abi_version_ptr)
++Sets the calling convention
++
++msoft-reg-count=
++Target RejectNegative Joined Var(m6809_soft_reg_count)
++Sets the number of soft registers that can be used
++
++mdret
++Target RejectNegative Mask(DRET)
++Put function call results in D, not X
++
++mfar-stack-param
++Target Mask(FAR_STACK_PARAM)
++Enable stack parameters to a farcall
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h gcc-4.6.4/gcc/config/m6809/m6809-protos.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809-protos.h	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,94 @@
++/* GCC for 6809 : machine-specific function prototypes
++
++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 __M6809_PROTOS_H__
++#define __M6809_PROTOS_H__
++
++void 					print_options (FILE *file);
++void 					m6809_cpu_cpp_builtins (void);
++void 					m6809_override_options (void);
++void 					m6809_init_builtins (void);
++unsigned int 		m6809_get_live_regs (void);
++const char * 		m6809_get_regs_printable (unsigned int regs);
++unsigned int 		m6809_get_regs_size (unsigned int regs);
++int 					m6809_function_has_type_attr_p (tree decl, const char *);
++int 					m6809_current_function_has_type_attr_p (const char *);
++int 					prologue_epilogue_required (void);
++int 					noreturn_functionp (rtx x);
++void 					output_function_prologue (FILE *file, int size);
++void 					output_function_epilogue (FILE *file, int size);
++int 					check_float_value (enum machine_mode mode, double *d, int overflow);
++void 					m6809_asm_named_section (const char *name, unsigned int flags, tree decl);
++void 					m6809_asm_file_start (void);
++void              m6809_output_ascii (FILE *fp, const char *str, unsigned long size);
++void              m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl);
++void              m6809_reorg (void);
++int               m6809_current_function_is_void (void);
++int               m6809_can_merge_pushpop_p (int op, int regs1, int regs2);
++int               m6809_function_value_regno_p (unsigned int regno);
++void              emit_prologue_insns (void);
++void              emit_epilogue_insns (bool);
++void              m6809_conditional_register_usage (void);
++void              m6809_output_quoted_string (FILE *asm_file, const char *string);
++int               m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage);
++int               m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode);
++int               power_of_two_p (unsigned int n);
++void              m6809_do_casesi (rtx index, rtx lower_bound, rtx range, rtx table_label, rtx default_label);
++void              m6809_output_addsi3 (int rtx_code, rtx *operands);
++rtx               m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump);
++void              expand_constant_shift (int code, rtx dst, rtx src, rtx count);
++int               m6809_single_operand_operator (rtx exp);
++
++#ifdef TREE_CODE
++int m6809_init_cumulative_args (CUMULATIVE_ARGS cum, tree fntype, rtx libname);
++#endif /* TREE_CODE */
++
++#ifdef RTX_CODE
++void 					print_direct_prefix (FILE *file, rtx addr);
++void 					print_operand (FILE *file, rtx x, int code);
++void 					print_operand_address (FILE *file, rtx addr);
++void 					notice_update_cc (rtx exp, rtx insn);
++enum 					reg_class m6809_preferred_reload_class (rtx x, enum reg_class regclass);
++rtx 					gen_rtx_const_high (rtx r);
++rtx 					gen_rtx_const_low (rtx r);
++rtx 					gen_rtx_register_pushpop (int pop_flag, int regs);
++void 					emit_libcall_insns (enum machine_mode mode, const char *name, rtx *operands, int count);
++const char *		output_branch_insn (enum rtx_code code, rtx *operands, int length);
++void 					output_far_call_insn (rtx *operands, int has_return);
++void 					m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt);
++rtx 					m6809_expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore);
++const char *      far_functionp (rtx x);
++rtx               m6809_function_value (const tree valtype, const tree func);
++void              m6809_output_shift_insn (int rtx_code, rtx *operands);
++
++const char * m6809_get_decl_bank (tree decl);
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p);
++rtx m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum);
++const char * far_function_type_p (tree type);
++void m6809_asm_trampoline_template(FILE *f);
++bool m6809_frame_pointer_required (void);
++int m6809_can_eliminate (int from, int to);
++int m6809_initial_elimination_offset (int from, int to);
++void m6809_emit_move_insn (rtx dst, rtx src);
++void m6809_split_shift (enum rtx_code code, rtx *operands);
++bool m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED);
++
++
++#endif /* RTX_CODE */
++
++#endif /* __M6809_PROTOS_H__ */
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/predicates.md gcc-4.6.4/gcc/config/m6809/predicates.md
+--- gcc-4.6.4-clean/gcc/config/m6809/predicates.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/predicates.md	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,78 @@
++;; Predicate definitions for Motorola 6809
++;; Copyright (C) 2006, 2007, 2008, 2009 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 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/>.
++
++;; whole_register_operand is like register_operand, but it
++;; does not allow SUBREGs.
++(define_predicate "whole_register_operand"
++  (and (match_code "reg")
++       (match_operand 0 "register_operand")))
++
++
++;; A predicate that matches any index register.  This can be used in nameless
++;; patterns and peepholes which need a 16-bit reg, but not D.
++(define_predicate "index_register_operand"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM || REGNO (op) == HARD_Y_REGNUM || REGNO (op) == HARD_U_REGNUM")))
++
++
++;; match only X
++(define_predicate "register_operand_x"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM")))
++
++;; match only D
++(define_predicate "register_operand_d"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_D_REGNUM")))
++
++
++;; Likwise, a replacement for general_operand which excludes
++;; SUBREGs.
++(define_predicate "whole_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")))
++
++
++(define_predicate "add_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")
++		 (match_test "REGNO (op) != SOFT_AP_REGNUM")))
++
++
++(define_predicate "shift_count_operand"
++  (and (match_code "const_int")
++     (and (match_operand 0 "const_int_operand")
++       (match_test "INTVAL (op) == 1 || INTVAL (op) == 8"))))
++
++
++;; A predicate that matches any bitwise logical operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "logical_bit_operator"
++	(ior (match_code "and") (match_code "ior") (match_code "xor")))
++
++
++;; A predicate that matches any shift or rotate operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "shift_rotate_operator"
++	(ior (match_code "ashift") (match_code "ashiftrt") (match_code "lshiftrt")
++	     (match_code "rotate") (match_code "rotatert")))
++
++
++(define_predicate "symbolic_operand" (match_code "symbol_ref"))
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-coco gcc-4.6.4/gcc/config/m6809/t-coco
+--- gcc-4.6.4-clean/gcc/config/m6809/t-coco	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-coco	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,6 @@
++# For a few minor differences in code generation on the CoCo...
++T_CFLAGS = -DTARGET_COCO
++
++# For doing the startup differently on the CoCo...
++CRT0STUFF_T_CFLAGS += -Wa,--globalize-symbols -DTARGET_COCO
++# vim: set filetype=make:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-m6809 gcc-4.6.4/gcc/config/m6809/t-m6809
+--- gcc-4.6.4-clean/gcc/config/m6809/t-m6809	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-m6809	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,64 @@
++
++# ranlib doesn't exist, so define it to 'true' to make it a no-op
++RANLIB_FOR_TARGET = true
++
++# Stubs for libgcc defined by m6809 are here
++LIB1ASMSRC = m6809/libgcc1.s
++
++# Here are the functions that are implemented within libgcc1.s
++LIB1ASMFUNCS = _mulhi3 _divhi3 _modhi3 _udivhi3 _umodhi3 \
++	_euclid _seuclid _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _softregs \
++	_ashlhi3 _ashrhi3 _lshrhi3
++
++# Flags to use when building libgcc.  IN_GCC does not seem necessary,
++# although the compile breaks without it.  -DDF=SF is required to set
++# the size of "double" to the same as the size of a "float".
++TARGET_LIBGCC2_CFLAGS =-DIN_GCC -Dinhibit_libc -DDF=SF -DLIBGCC2_HAS_SF_MODE=0 -DLIBGCC2_HAS_DF_MODE=0
++
++LIB2ADDEH =
++LIB2ADDEHSTATIC =
++LIB2ADDEHSHARED =
++
++LIBGCC2_DEBUG_CFLAGS =
++LIBGCC2_CFLAGS = -Os $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
++
++# Multilib information
++# This creates multiple versions of libgcc.a for each set of incompatible
++# -mxxx options.
++MULTILIB_OPTIONS  = fpic mdret
++MULTILIB_DIRNAMES =
++MULTILIB_MATCHES  =
++MULTILIB_EXCEPTIONS =
++EXTRA_MULTILIB_PARTS = crt0.o
++
++LIBGCC = stmp-multilib
++INSTALL_LIBGCC = install-multilib
++
++# We want fine grained libraries, so use the new code to build the
++# floating point emulation libraries.
++FPBIT = fp-bit.c
++
++fp-bit.c: $(srcdir)/config/fp-bit.c
++	echo '#define FLOAT' > fp-bit.c
++	echo '#define FLOAT_ONLY' >> fp-bit.c
++	echo '#define CMPtype HItype' >> fp-bit.c
++	echo '#define SMALL_MACHINE' >> fp-bit.c
++	echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
++	echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
++	echo '#endif' 		>> fp-bit.c
++	echo '#define DI SI'	>> fp-bit.c
++	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++
++# crt0.o is built from the following source file
++CRT0_S = $(srcdir)/config/m6809/crt0.S
++MCRT0_S = $(srcdir)/config/m6809/crt0.S
++
++# Flags to use when building crt0.o
++CRT0STUFF_T_CFLAGS += -fno-builtin -nostartfiles -nostdlib
++
++# Assemble startup files.
++$(T)crt0.o: $(CRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)crt0.o -x assembler-with-cpp $(CRT0_S)
++
++$(T)mcrt0.o: $(MCRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)mcrt0.o -x assembler-with-cpp $(MCRT0_S)
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-sim gcc-4.6.4/gcc/config/m6809/t-sim
+--- gcc-4.6.4-clean/gcc/config/m6809/t-sim	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-sim	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1 @@
++CRT0STUFF_T_CFLAGS += -DTARGET_SIM
+diff -urN gcc-4.6.4-clean/gcc/config.gcc gcc-4.6.4/gcc/config.gcc
+--- gcc-4.6.4-clean/gcc/config.gcc	2013-03-06 10:40:07.000000000 -0700
++++ gcc-4.6.4/gcc/config.gcc	2017-11-28 21:12:11.156911596 -0700
+@@ -375,6 +375,9 @@
+         cpu_type=m32r
+ 	extra_options="${extra_options} g.opt"
+         ;;
++m6809-*-*)
++        cpu_type=m6809
++        ;;
+ m68k-*-*)
+ 	extra_headers=math-68881.h
+ 	;;
+@@ -1706,6 +1709,12 @@
+ 		thread_file='posix'
+ 	fi
+ 	;;
++m6809-coco-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-coco"
++	;;
++m6809-*-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-sim"
++	;;
+ # m68hc11 and m68hc12 share the same machine description.
+ m68hc11-*-*|m6811-*-*)
+ 	tm_file="dbxelf.h elfos.h usegas.h newlib-stdint.h m68hc11/m68hc11.h"
+diff -urN gcc-4.6.4-clean/gcc/gcse.c gcc-4.6.4/gcc/gcse.c
+--- gcc-4.6.4-clean/gcc/gcse.c	2011-02-02 23:04:04.000000000 -0700
++++ gcc-4.6.4/gcc/gcse.c	2017-11-28 21:12:11.156911596 -0700
+@@ -833,7 +833,6 @@
+ 	      max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
+ 	      if (max_distance == 0)
+ 		return 0;
+-
+ 	      gcc_assert (max_distance > 0);
+ 	    }
+ 	  else
+diff -urN gcc-4.6.4-clean/gcc/libgcc2.c gcc-4.6.4/gcc/libgcc2.c
+--- gcc-4.6.4-clean/gcc/libgcc2.c	2011-01-03 13:52:22.000000000 -0700
++++ gcc-4.6.4/gcc/libgcc2.c	2017-11-28 21:12:11.156911596 -0700
+@@ -485,6 +485,7 @@
+ #endif
+ 
+ #ifdef L_bswapsi2
++#if MIN_UNITS_PER_WORD > 1
+ SItype
+ __bswapsi2 (SItype u)
+ {
+@@ -494,7 +495,9 @@
+ 	  | (((u) & 0x000000ff) << 24));
+ }
+ #endif
++#endif
+ #ifdef L_bswapdi2
++#if LONG_LONG_TYPE_SIZE > 32
+ DItype
+ __bswapdi2 (DItype u)
+ {
+@@ -508,6 +511,7 @@
+ 	  | (((u) & 0x00000000000000ffull) << 56));
+ }
+ #endif
++#endif
+ #ifdef L_ffssi2
+ #undef int
+ int
+@@ -1280,7 +1284,7 @@
+ UDWtype
+ __fixunssfDI (SFtype a)
+ {
+-#if LIBGCC2_HAS_DF_MODE
++#if LIBGCC2_HAS_DF_MODE || (FLT_MANT_DIG >= W_TYPE_SIZE)
+   /* Convert the SFtype to a DFtype, because that is surely not going
+      to lose any bits.  Some day someone else can write a faster version
+      that avoids converting to DFtype, and verify it really works right.  */
+@@ -1298,7 +1302,7 @@
+ 
+   /* Assemble result from the two parts.  */
+   return ((UDWtype) hi << W_TYPE_SIZE) | lo;
+-#elif FLT_MANT_DIG < W_TYPE_SIZE
++#else
+   if (a < 1)
+     return 0;
+   if (a < Wtype_MAXp1_F)
+@@ -1334,8 +1338,6 @@
+       return (DWtype)counter << shift;
+     }
+   return -1;
+-#else
+-# error
+ #endif
+ }
+ #endif
+diff -urN gcc-4.6.4-clean/gcc/longlong.h gcc-4.6.4/gcc/longlong.h
+--- gcc-4.6.4-clean/gcc/longlong.h	2011-10-04 01:28:50.000000000 -0600
++++ gcc-4.6.4/gcc/longlong.h	2017-11-28 21:12:11.160911575 -0700
+@@ -528,6 +528,11 @@
+ 	   : "cbit")
+ #endif /* __M32R__ */
+ 
++#if defined (__m6309__) || defined (__m6809__)
++#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
++#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctz (X))
++#endif
++
+ #if defined (__mc68000__) && W_TYPE_SIZE == 32
+ #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+   __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
+diff -urN gcc-4.6.4-clean/gcc/Makefile.in gcc-4.6.4/gcc/Makefile.in
+--- gcc-4.6.4-clean/gcc/Makefile.in	2013-04-01 02:32:34.000000000 -0600
++++ gcc-4.6.4/gcc/Makefile.in	2017-11-28 21:12:11.160911575 -0700
+@@ -2003,14 +2003,14 @@
+ 
+ # Compile the start modules crt0.o and mcrt0.o that are linked with
+ # every program
+-$(T)crt0.o: s-crt0 ; @true
+-$(T)mcrt0.o: s-crt0; @true
++crt0.o: s-crt0 ; @true
++mcrt0.o: s-crt0; @true
+ 
+ s-crt0:	$(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)crt0.o -c $(CRT0_S)
++	  -o crt0.o -c $(CRT0_S)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)mcrt0.o -c $(MCRT0_S)
++	  -o mcrt0.o -c $(MCRT0_S)
+ 	$(STAMP) s-crt0
+ #
+ # Compiling object files from source files.
+diff -urN gcc-4.6.4-clean/gcc/opth-gen.awk gcc-4.6.4/gcc/opth-gen.awk
+--- gcc-4.6.4-clean/gcc/opth-gen.awk	2011-02-08 10:41:00.000000000 -0700
++++ gcc-4.6.4/gcc/opth-gen.awk	2017-11-28 21:12:11.160911575 -0700
+@@ -121,7 +121,7 @@
+ END {
+ print "/* This file is auto-generated by opth-gen.awk.  */"
+ print ""
+-print "#ifndef OPTIONS_H"
++print "#if !defined(OPTIONS_H) && !defined(IN_LIBGCC2)"
+ print "#define OPTIONS_H"
+ print ""
+ print "#include \"flag-types.h\""
+@@ -432,18 +432,9 @@
+ 
+ for (i = 0; i < n_opts; i++) {
+ 	opt = opt_args("InverseMask", flags[i])
+-	if (opt ~ ",") {
+-		vname = var_name(flags[i])
+-		macro = "OPTION_"
+-		mask = "OPTION_MASK_"
+-		if (vname == "") {
+-			vname = "target_flags"
+-			macro = "TARGET_"
+-			mask = "MASK_"
+-		}
+-		print "#define " macro nth_arg(1, opt) \
+-		      " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
+-	}
++	if (opt ~ ",")
++		print "#define TARGET_" nth_arg(1, opt) \
++		      " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
+ }
+ print ""
+ 
+diff -urN gcc-4.6.4-clean/gcc/tree.h gcc-4.6.4/gcc/tree.h
+--- gcc-4.6.4-clean/gcc/tree.h	2011-10-06 13:57:52.000000000 -0600
++++ gcc-4.6.4/gcc/tree.h	2017-11-28 21:12:11.160911575 -0700
+@@ -3563,6 +3563,8 @@
+   TI_UINTDI_TYPE,
+   TI_UINTTI_TYPE,
+ 
++  TI_UINT8_TYPE,
++  TI_UINT16_TYPE,
+   TI_UINT32_TYPE,
+   TI_UINT64_TYPE,
+ 
+diff -urN gcc-4.6.4-clean/gcc/version.c gcc-4.6.4/gcc/version.c
+--- gcc-4.6.4-clean/gcc/version.c	2009-04-21 13:03:23.000000000 -0600
++++ gcc-4.6.4/gcc/version.c	2017-11-28 21:20:44.918095673 -0700
+@@ -21,16 +21,16 @@
+ 
+ /* This is the location of the online document giving instructions for
+    reporting bugs.  If you distribute a modified version of GCC,
+-   please configure with --with-bugurl pointing to a document giving
+-   instructions for reporting bugs to you, not us.  (You are of course
+-   welcome to forward us bugs reported to you, if you determine that
+-   they are not bugs in your modifications.)  */
++   please change this to refer to a document giving instructions for
++   reporting bugs to you, not us.  (You are of course welcome to
++   forward us bugs reported to you, if you determine that they are
++   not bugs in your modifications.)  */
+ 
+-const char bug_report_url[] = BUGURL;
++const char bug_report_url[] = "<URL:http://lost.l-w.ca/coco/lwtools/>";
+ 
+ /* The complete version string, assembled from several pieces.
+    BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the
+    Makefile.  */
+ 
+-const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION;
++const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION " (gcc6809lw pl8)";
+ const char pkgversion_string[] = PKGVERSION;
+diff -urN gcc-4.6.4-clean/libgcc/config.host gcc-4.6.4/libgcc/config.host
+--- gcc-4.6.4-clean/libgcc/config.host	2011-11-23 15:15:54.000000000 -0700
++++ gcc-4.6.4/libgcc/config.host	2017-11-28 21:12:11.160911575 -0700
+@@ -371,6 +371,8 @@
+  	;;
+ m32rle-*-linux*)
+ 	;;
++m6809*)
++	;;
+ m68hc11-*-*|m6811-*-*)
+         ;;
+ m68hc12-*-*|m6812-*-*)
+diff -urN gcc-4.6.4-clean/libgcc/fixed-obj.mk gcc-4.6.4/libgcc/fixed-obj.mk
+--- gcc-4.6.4-clean/libgcc/fixed-obj.mk	2007-09-17 16:18:13.000000000 -0600
++++ gcc-4.6.4/libgcc/fixed-obj.mk	2017-11-28 21:12:11.160911575 -0700
+@@ -23,7 +23,7 @@
+ #$(info $o$(objext): -DL$($o-label) $($o-opt))
+ 
+ $o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
+-	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
++	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide) -save-temps
+ 
+ ifeq ($(enable_shared),yes)
+ $(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
+diff -urN gcc-4.6.4-clean/libgcc/Makefile.in gcc-4.6.4/libgcc/Makefile.in
+--- gcc-4.6.4-clean/libgcc/Makefile.in	2012-12-04 12:11:33.000000000 -0700
++++ gcc-4.6.4/libgcc/Makefile.in	2017-11-28 21:12:11.160911575 -0700
+@@ -374,8 +374,8 @@
+ # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
+ lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
+ $(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(lib2funcs-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -410,8 +410,9 @@
+ # Build LIB2_DIVMOD_FUNCS.
+ lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
+ $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  -fexceptions -fnon-call-exceptions $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c \
++	  -fexceptions -fnon-call-exceptions $(vis_hide) -save-temps
+ libgcc-objects += $(lib2-divmod-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -443,7 +444,8 @@
+ ifneq ($(FPBIT),)
+ fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
+ $(fpbit-o): %$(objext): $(FPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
++	ln -sf $(FPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(fpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -458,7 +460,8 @@
+ ifneq ($(DPBIT),)
+ dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
+ $(dpbit-o): %$(objext): $(DPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
++	ln -sf $(DPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(dpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+diff -urN gcc-4.6.4-clean/README.LW gcc-4.6.4/README.LW
+--- gcc-4.6.4-clean/README.LW	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/README.LW	2017-11-28 21:12:11.160911575 -0700
+@@ -0,0 +1,14 @@
++This is a port of gcc6809 which is designed to work with the lwtools
++cross-assembler and linker package.  You will need several scripts from that
++package, available at http://lost.l-w.ca/coco/lwtools/, in order to use
++this.  Instructions for building are present in the lwtools package.
++
++This work is based extensively on the gcc6809 4.3.4-3 release by Brian
++Dominy (brian@oddchange.com) with some significant renovations to make it
++work with gcc 4.6.1.
++
++There is no guarantee that it will work for any particular purpose you
++choose to put it to.
++
++If you run into any problems, contact William Astle (lost@l-w.ca). DO NOT
++contact the main GCC developers!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extra/gcc6809lw-4.6.4-9.patch	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,8172 @@
+diff -urN gcc-4.6.4-clean/config.sub gcc-4.6.4/config.sub
+--- gcc-4.6.4-clean/config.sub	2010-05-25 07:22:07.000000000 -0600
++++ gcc-4.6.4/config.sub	2017-11-28 21:12:11.136911706 -0700
+@@ -313,7 +313,7 @@
+ 	c6x)
+ 		basic_machine=tic6x-unknown
+ 		;;
+-	m6811 | m68hc11 | m6812 | m68hc12 | picochip)
++	m6809 | m6811 | m68hc11 | m6812 | m68hc12 | picochip)
+ 		# Motorola 68HC11/12.
+ 		basic_machine=$basic_machine-unknown
+ 		os=-none
+@@ -354,7 +354,7 @@
+ 	| i*86-* | i860-* | i960-* | ia64-* \
+ 	| ip2k-* | iq2000-* \
+ 	| lm32-* \
+-	| m32c-* | m32r-* | m32rle-* \
++	| m32c-* | m32r-* | m32rle-* | m6809-* \
+ 	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ 	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+ 	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+@@ -509,6 +509,10 @@
+ 		basic_machine=arm-unknown
+ 		os=-cegcc
+ 		;;
++	coco)
++		basic_machine=coco
++		os=-none
++		;;
+ 	convex-c1)
+ 		basic_machine=c1-convex
+ 		os=-bsd
+diff -urN gcc-4.6.4-clean/configure gcc-4.6.4/configure
+--- gcc-4.6.4-clean/configure	2011-12-18 03:03:44.000000000 -0700
++++ gcc-4.6.4/configure	2017-11-28 21:12:11.136911706 -0700
+@@ -3439,6 +3439,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/configure.ac gcc-4.6.4/configure.ac
+--- gcc-4.6.4-clean/configure.ac	2011-11-18 04:45:44.000000000 -0700
++++ gcc-4.6.4/configure.ac	2017-11-28 21:12:11.140911685 -0700
+@@ -885,6 +885,9 @@
+   m32r-*-*)
+     noconfigdirs="$noconfigdirs ${libgcj}"
+     ;;
++  m6809*)
++    noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 target-libgloss ${libgcj}"
++    ;;
+   m68hc11-*-*|m6811-*-*|m68hc12-*-*|m6812-*-*)
+     noconfigdirs="$noconfigdirs target-libstdc++-v3 ${libgcj}"
+     libgloss_dir=m68hc11
+diff -urN gcc-4.6.4-clean/gcc/calls.c gcc-4.6.4/gcc/calls.c
+--- gcc-4.6.4-clean/gcc/calls.c	2012-02-09 10:27:25.000000000 -0700
++++ gcc-4.6.4/gcc/calls.c	2017-11-28 21:12:11.140911685 -0700
+@@ -2561,7 +2561,7 @@
+ 	 call sequence.
+ 	 Also do the adjustments before a throwing call, otherwise
+ 	 exception handling can fail; PR 19225. */
+-      if (pending_stack_adjust >= 32
++      if (pending_stack_adjust >= 8
+ 	  || (pending_stack_adjust > 0
+ 	      && (flags & ECF_MAY_BE_ALLOCA))
+ 	  || (pending_stack_adjust > 0
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/crt0.S gcc-4.6.4/gcc/config/m6809/crt0.S
+--- gcc-4.6.4-clean/gcc/config/m6809/crt0.S	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/crt0.S	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,182 @@
++;;;
++;;; Copyright 2006, 2007, 2008, 2009 by Brian Dominy <brian@oddchange.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/>.
++
++	/* Declare external for main() */
++	.globl	_main
++
++/* The startup is heavily dependent on the type of machine and
++OS environment that is available at the start point.
++For the most part, the general idea is the same across machines,
++but the implementation is vastly different.  This is managed via
++conditional compiles throughout the startup code for each of the
++supported machines. */
++
++#if defined(TARGET_COCO) /* CoCo memory map */
++
++#define COCO_RAMROM_MODE 0xFFDE
++#define COCO_ALLRAM_MODE 0xFFDF
++#define COCO_PAGE1 0xFFD5
++
++/* SAM M1 and M0 adjusts the memory size */
++
++#define BASIC_WARMSTART_FLAG 0x0071
++#define BASIC_START 0xA027
++
++#define __STACK_TOP 0x6800
++
++#elif defined(TARGET_PROTO) /* Prototype hardware. Customisation of this section is expected! */
++
++#define __STACK_TOP 0x8000
++
++#else /* Simulator (default) memory map */
++
++#define SIM_EXIT_REG 0xFF01
++
++#define __STACK_TOP 0xFE00
++
++#endif
++
++	.area	.data
++	.area	.ctors
++	.area	.dtors
++	.area	.bss
++
++	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __exit : Exit point from the program
++	;;; For simulation, this writes to a special I/O register that
++	;;; the simulator interprets as end-of-program.
++	;;;
++	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++ 	.globl	__exit
++__exit:
++#if defined(TARGET_COCO)
++	;; Go back to ROM/RAM mode
++	sta	COCO_RAMROM_MODE
++	clr	BASIC_WARMSTART_FLAG
++	jmp	BASIC_START
++#elif defined(TARGET_PROTO) /* Prototype hardware. Customisation of this section is expected! */
++	tfr	x,d
++__ex@0	bra	__ex@0
++#else /* Simulator */
++	tfr	x,d
++	stb	SIM_EXIT_REG
++	bra	__exit
++#endif
++
++	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	;;;
++	;;; __start : Entry point to the program
++	;;;
++	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area	.text
++	.globl	__start
++__start:
++
++#if defined(HAVE_DIRECT)
++	;; Initialize the direct page pointer
++	lda	#<s_.direct
++	tfr	a,dp
++#endif
++
++#if defined(TARGET_COCO)
++	;; Turn off interrupts
++	orcc #(0x10|0x40)
++
++	;; Setup All RAM Mode
++	sta COCO_ALLRAM_MODE
++#endif
++
++	;; Initialize the stack. NMI works after this point.
++	lds	#__STACK_TOP - 2
++
++	;; Set up hardware; console device, video etc
++#if defined(TARGET_PROTO) /* Prototype hardware. Customisation of this section is expected! */
++	lbsr	_initialise_hardware
++#endif
++
++	;; Call any constructors that may be present
++	ldu	#s_.ctors
++__ctors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__ctors_done
++	jsr	,y
++	bra	__ctors_loop
++__ctors_done:
++
++	;; Enable interrupts if not on COCO
++#if !defined(TARGET_COCO)
++	andcc	#~(0x10|0x40)
++#endif
++
++	;; Set up the environment
++	ldu	#s_.bss
++
++	;; Set up argc/argv arrays
++
++	;; Call the main function.  The exit code will
++	;; be returned in the X register, unless compiled
++	;; with -mdret, in which case it comes back in D.
++	jsr	_main
++
++	;; Call any destructors
++	ldu	#s_.dtors
++__dtors_loop:
++	ldy	,u++
++	cmpy	#0
++	beq	__dtors_done
++	jsr	,y
++	bra	__dtors_loop
++__dtors_done:
++
++	;; If main returns, then invoke _*exit() to stop the program
++	;; The C library doesn't support -mdret yet, so move the
++	;; argument first.
++#if defined(__DRET__)
++	tfr	d,x
++#endif
++	;; The newlib exit() is an absolute pig. In calling __call_exitprocs(), it brings with
++	;; it the kitchen sink, notably malloc() and friends which are *enormous*.
++	jmp	__exit
++
++	;;;
++	;;; __crt0_vector : Default handler for interrupts
++	;;;
++	.area	.text
++___crt0_vector:
++	;; The default behavior is to simply ignore all
++	;; non-reset interrupts.
++	rti
++
++	;;;
++	;;; vector : The interrupt vector table
++	;;; The linker will ensure that this gets loaded at address 0xFFF0.
++	;;;
++	.area	vector
++vectors:
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	___crt0_vector
++	.word	__start
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s gcc-4.6.4/gcc/config/m6809/libgcc1.s
+--- gcc-4.6.4-clean/gcc/config/m6809/libgcc1.s	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/libgcc1.s	2017-11-28 21:12:11.152911619 -0700
+@@ -0,0 +1,511 @@
++/* libgcc routines for m6809
++   Copyright (C) 2006 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 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/>.  */
++
++/* As a special exception, if you link this library with other files,
++   some of which are compiled with GCC, to produce an executable,
++   this library does not by itself cause the resulting executable
++   to be covered by the GNU General Public License.
++   This exception does not however invalidate any other reasons why
++   the executable file might be covered by the GNU General Public License.  */
++
++
++#define SIGFPE jmp _abort
++
++
++	; Shift functions
++	; On input, D is value to be shifted, and X has shift count.
++	; Result is also in D.
++
++#ifdef L_ashlhi3
++	.area .text
++	.globl _ashlhi3
++_ashlhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	aslb
++	rola
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++#ifdef L_ashrhi3
++	.area .text
++	.globl _ashrhi3
++_ashrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	asra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++#ifdef L_lshrhi3
++	.area .text
++	.globl _lshrhi3
++_lshrhi3:
++	pshs	x
++1$:
++	leax	-1,x
++	cmpx	#-1
++	beq	2$
++	lsra
++	rorb
++	bra	1$
++2$:
++	puls	x,pc
++#endif
++
++
++
++#ifdef L_softregs
++	.area		direct
++	.globl	m0, m1, m2, m3, m4, m5, m6, m7
++	.globl	m8, m9, m10, m11, m12, m13, m14, m15
++m0: .blkb 1
++m1: .blkb 1
++m2: .blkb 1
++m3: .blkb 1
++m4: .blkb 1
++m5: .blkb 1
++m6: .blkb 1
++m7: .blkb 1
++m8: .blkb 1
++m9: .blkb 1
++m10: .blkb 1
++m11: .blkb 1
++m12: .blkb 1
++m13: .blkb 1
++m14: .blkb 1
++m15: .blkb 1
++#endif
++
++
++#ifdef L_ashlsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashlsi3_one:
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	rts
++#endif
++
++#ifdef L_ashlsi3
++	/* X points to the SImode (source/dest)
++		B is the count */
++_ashlsi3:
++	pshs	u
++	cmpb	#16
++	blt	try8
++	subb	#16
++	; Shift by 16
++	ldu	2,x
++	stu	,x
++try8:
++	cmpb	#8
++	blt	try_rest
++	subb	#8
++	; Shift by 8
++
++try_rest:
++	tstb
++	beq	done
++do_rest:
++	; Shift by 1
++	asl	3,x
++	rol	2,x
++	rol	1,x
++	rol	,x
++	decb
++	bne	do_rest
++done:
++	puls	u,pc
++#endif
++
++#ifdef L_ashrsi3_one
++	.area		.text
++	.globl	_ashlsi3_one
++_ashrsi3_one:
++	asr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_lshrsi3_one
++	.area		.text
++	.globl	_lshrsi3_one
++_lshrsi3_one:
++	lsr	,x
++	ror	1,x
++	ror	2,x
++	ror	3,x
++	rts
++#endif
++
++
++#ifdef L_clzsi2
++	.area .text
++	.globl ___clzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of leading zeros
++	; This function destroys the value in D.
++___clzhi2:
++	pshs	x
++	; Find the offset of the leftmost '1' bit in
++	; the left half of the word.
++	;
++	; Bits are numbered in the table with 1 meaning the
++	; LSB and 8 meaning the MSB.
++	;
++	; If nonzero, then clz is 8-a.
++	tfr	x,d
++	ldx	#___clz_tab
++	tfr	a,b
++	clra
++	ldb	d,x
++	bne	upper_bit_set
++
++lower_bit_set:
++	; If the upper byte is zero, then check the lower
++	; half of the word.  Return 16-a.
++	puls	d
++	clra
++	ldb	d,x
++	negb
++	addb	#16
++	bra	done
++
++upper_bit_set:
++	negb
++	addb	#8
++	puls	x
++
++done:
++	tfr	d,x
++	puls	pc
++#endif
++
++#ifdef L_clzdi2
++	.area .text
++	.globl ___clzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___clzsi2:
++	; Check the upper 16-bit word
++	; If it is not zero, then return clzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	2,s
++	lbne	___clzhi2
++	ldx	4,s
++	jsr	___clzhi2
++	leax	16,x
++	rts
++#endif
++
++#ifdef L_ctzsi2
++	.area .text
++	.globl ___ctzhi2
++	; Input: X = 16-bit unsigned integer
++	; Output: X = number of trailing zeros
++	; F(x) = 15 - clzhi2(X & -x)
++	; This function destroys the value in D.
++___ctzhi2:
++	tfr	x,d
++	coma
++	comb
++	addd	#1
++	pshs	a
++	pshs	b
++	tfr	x,d
++	andb	,s+
++	anda	,s+
++	tfr	d,x
++	jsr	___clzhi2
++	tfr	x,d
++	subd	#16
++	coma
++	comb
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_ctzdi2
++	.area .text
++	.globl ___ctzsi2
++	; Input: 32-bit unsigned integer is on the stack, just
++	; above the return address
++	; Output: X = number of leading zeros
++___ctzsi2:
++	; Check the lower 16-bit word
++	; If it is not zero, then return ctzhi2(X).
++	; A branch can be used instead of a call since no
++	; postprocessing is needed.  Use long branch form
++	; though since functions may not be near each other.
++	ldx	4,s
++	lbne	___ctzhi2
++	ldx	2,s
++	jsr	___ctzhi2
++	leax	16,x
++	rts
++#endif
++
++
++#ifdef L_mulhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___mulhi3 - signed/unsigned multiply
++;;; Called by GCC to implement 16x16 multiplication
++;;; Arguments: Two 16-bit values, one in stack, one in X.
++;;; Result: 16-bit result in X
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _mulhi3
++_mulhi3:
++	pshs	x
++	lda   5,s   ; left msb * right lsb * 256
++	ldb   ,s
++	mul
++	tfr   b,a
++	clrb
++	tfr   d,x
++	ldb   1,s   ; left lsb * right msb * 256
++	lda   4,s
++	mul
++	tfr   b,a
++	clrb
++	leax  d,x
++	ldb   1,s   ; left lsb * right lsb
++	lda   5,s
++	mul
++	leax  d,x
++	puls	d,pc  ; kill D to remove initial push
++#endif
++
++
++#ifdef L_divhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___divhi3 - signed division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _divhi3
++_divhi3:
++	ldd	2,s
++	bne	do_div		; check dividend
++	SIGFPE
++do_div:
++	pshs	x
++	jsr	_seuclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_modhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___modhi3 - signed modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _modhi3
++_modhi3:
++	ldd	2,s
++	bne	do_mod		; check dividend
++	SIGFPE
++do_mod:
++	pshs	x
++	jsr	_seuclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++
++#ifdef L_udivhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___udivhi3 - unsigned division
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _udivhi3
++_udivhi3:
++	ldd	2,s
++	bne	do_udiv		; check dividend
++	SIGFPE
++do_udiv:
++	pshs	x
++	jsr	_euclid
++	puls	x,pc
++#endif
++
++
++#ifdef L_umodhi3
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++;;; ___umodhi3 - unsigned modulo
++;;; Arguments: Dividend in X, divisor on the stack
++;;; Returns result in X.
++;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
++	.area .text
++	.globl _umodhi3
++_umodhi3:
++	ldd	2,s
++	bne	do_umod		; check dividend
++	SIGFPE
++do_umod:
++	pshs	x
++	jsr	_euclid
++	leas	2,s
++	tfr	d,x
++	rts
++#endif
++
++
++#ifdef L_euclid
++;	unsigned euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _euclid
++;	quotient on the stack (left)
++;	modulus in d
++
++	.area	.text
++	.globl	_euclid
++	left=5
++	right=1			; word
++	count=0			; byte
++	CARRY=1			; alias
++_euclid:
++	leas	-3,s		; 2 local variables
++	clr	count,s		; prescale divisor
++	inc	count,s
++	tsta
++presc:
++	bmi	presc_done
++	inc	count,s
++	aslb
++	rola
++	bra	presc
++presc_done:
++	std	right,s
++	ldd	left,s
++	clr	left,s		; quotient = 0
++	clr	left+1,s
++mod1:
++	subd	right,s		; check subtract
++	bcc	mod2
++	addd	right,s
++	andcc	#~CARRY
++	bra	mod3
++mod2:
++	orcc	#CARRY
++mod3:
++	rol	left+1,s	; roll in carry
++	rol	left,s
++	lsr	right,s
++	ror	right+1,s
++	dec	count,s
++	bne	mod1
++	leas	3,s
++	rts
++#endif
++
++#ifdef L_seuclid
++;	signed euclidean division
++;	calling: (left / right)
++;		push left
++;		ldd right
++;		jsr _seuclid
++;	quotient on the stack (left)
++;	modulus in d
++	.area	.text
++	.globl	_seuclid
++	left=6
++	right=2
++	quot_sign=1
++	mod_sign=0
++_seuclid:
++	leas	-4,s		; 3 local variables
++	std	right,s
++	clr	mod_sign,s
++	clr	quot_sign,s
++	ldd	left,s
++	bge	mod_abs
++	inc	mod_sign,s	; sign(mod) = sign(left)
++	inc	quot_sign,s
++	bsr	negd		; abs(left) -> D
++mod_abs:
++	pshs	b,a		; push abs(left)
++	ldd	right+2,s	; all references shifted by 2
++	bge	quot_abs
++	dec	quot_sign+2,s	; sign(quot) = sign(left) XOR sign(right)
++	bsr	negd		; abs(right) -> D
++quot_abs:
++	jsr	_euclid		; call (unsigned) euclidean division
++	std	right+2,s
++	puls	a,b		; quot -> D
++	tst	quot_sign,s	; all references no longer shifted
++	beq	quot_done
++	bsr	negd
++quot_done:
++	std	left,s		; quot -> left
++	ldd	right,s
++	tst	mod_sign,s
++	beq	mod_done
++	bsr	negd
++mod_done:
++	leas	4,s		; destroy stack frame
++	rts
++
++negd:				; self-explanatory !
++	nega
++	negb
++	sbca	#0
++	rts
++#endif
++
++
++
++#ifdef L_pending_addsi3
++_addsi3:
++	rts
++#endif /* L_pending_addsi3 */
++
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.c gcc-4.6.4/gcc/config/m6809/m6809.c
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.c	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.c	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,3027 @@
++/*-------------------------------------------------------------------
++	FILE: m6809.c
++-------------------------------------------------------------------*/
++/* Subroutines for insn-output.c for MC6809.
++   Copyright (C) 1989-2007 Free Software Foundation, Inc.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ major cleanup, improvements, and upgrade to gcc 3.4 by Brian Dominy
++ (brian@oddchange.com)
++
++ additional adjustments, etc., for gcc 4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++#include <string.h>
++#include <time.h>
++#include <sys/types.h>
++#include <sys/timeb.h>
++#include <stdio.h>
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tm.h"
++#include "tree.h"
++#include "rtl.h"
++#include "tm_p.h"
++#include "regs.h"
++#include "flags.h"
++#include "hard-reg-set.h"
++#include "real.h"
++#include "tree.h"
++#include "insn-config.h"
++#include "conditions.h"
++#include "insn-flags.h"
++#include "output.h"
++#include "insn-attr.h"
++#include "function.h"
++#include "target.h"
++#include "target-def.h"
++#include "expr.h"
++#include "recog.h"
++#include "cpplib.h"
++#include "c-family/c-pragma.h"
++#include "c-family/c-common.h"
++#include "toplev.h"
++#include "optabs.h"
++#include "version.h"
++#include "df.h"
++#include "rtlhooks-def.h"
++
++/* macro to return TRUE if length of operand mode is one byte */
++#define BYTE_MODE(X) ((GET_MODE_SIZE (GET_MODE (X))) == 1)
++
++
++/* REAL_REG_P(x) is a true if the rtx 'x' represents a real CPU
++register and not a fake one that is emulated in software. */
++#define REAL_REG_P(x) (REG_P(x) && !M_REG_P(x))
++
++/*-------------------------------------------------------------------
++    Target hooks, moved from target.h
++-------------------------------------------------------------------*/
++static void m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED);
++
++#undef TARGET_ENCODE_SECTION_INFO
++#define TARGET_ENCODE_SECTION_INFO m6809_encode_section_info
++
++#undef TARGET_ASM_FILE_START
++#define TARGET_ASM_FILE_START m6809_asm_file_start
++
++#undef TARGET_ASM_ALIGNED_HI_OP
++#define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_ALIGNED_SI_OP
++#define TARGET_ASM_ALIGNED_SI_OP NULL
++
++#undef TARGET_ASM_UNALIGNED_HI_OP
++#define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
++
++#undef TARGET_ASM_UNALIGNED_SI_OP
++#define TARGET_ASM_UNALIGNED_SI_OP NULL
++
++#undef TARGET_RTX_COSTS
++#define TARGET_RTX_COSTS m6809_rtx_costs
++
++#undef TARGET_ATTRIBUTE_TABLE
++#define TARGET_ATTRIBUTE_TABLE m6809_attribute_table
++
++#undef TARGET_INIT_BUILTINS
++#define TARGET_INIT_BUILTINS m6809_init_builtins
++
++#undef TARGET_EXPAND_BUILTIN
++#define TARGET_EXPAND_BUILTIN m6809_expand_builtin
++
++#undef TARGET_DEFAULT_TARGET_FLAGS
++#define TARGET_DEFAULT_TARGET_FLAGS (MASK_REG_ARGS | MASK_DIRECT)
++
++#undef TARGET_FUNCTION_OK_FOR_SIBCALL
++#define TARGET_FUNCTION_OK_FOR_SIBCALL m6809_function_ok_for_sibcall
++
++#undef TARGET_ASM_TRAMPOLINE_TEMPLATE
++#define TARGET_ASM_TRAMPOLINE_TEMPLATE m6809_asm_trampoline_template
++
++#undef TARGET_TRAMPOLINE_INIT
++#define TARGET_TRAMPOLINE_INIT m6809_initialize_trampoline
++
++#undef TARGET_FRAME_POINTER_REQUIRED
++#define TARGET_FRAME_POINTER_REQUIRED m6809_frame_pointer_required
++
++#undef TARGET_OPTION_OVERRIDE
++#define TARGET_OPTION_OVERRIDE m6809_override_options
++
++/* External variables used */
++extern int reload_completed;   /* set in toplev.c */
++extern FILE *asm_out_file;
++
++static int last_mem_size;   /* operand size (bytes) */
++
++/* True if the section was recently changed and another .area
++ * directive needs to be output before emitting the next label. */
++int section_changed = 0;
++
++/* Section names.  The defaults here are used until an
++ * __attribute__((section)) is seen that changes it. */
++char code_section_op[128] = "\n\t.area\t.text";
++char data_section_op[128] = "\n\t.area\t.data";
++char bss_section_op[128] = "\n\t.area\t.bss";
++const char *code_bank_option = 0;
++
++/* TRUE if the direct mode prefix might be valid in this context.
++ * This is set by 'print_address' prior to calling output_addr_const,
++ * which performs into 'print_direct_prefix' to do the final checks. */
++static int check_direct_prefix_flag;
++
++/* Nonzero if an address is being printed in a context which does not
++ * permit any PIC modifications to the address */
++static int pic_ok_for_addr_p = 1;
++
++/* Current code page.  This supports machines which can do bank
++ * switching to allow for more than 64KB of code/data. */
++char far_code_page[64];
++
++/* Current bank name */
++static char current_bank_name[8] = "-1";
++
++/* Default bank name */
++static char default_code_bank_name[8] = "-1";
++
++/* Direct memory reserved as soft registers */
++unsigned int m6809_soft_regs = 0;
++
++/* ABI version */
++unsigned int m6809_abi_version = M6809_ABI_VERSION_REGS;
++
++
++/**
++ * Called after options have been parsed.
++ * If overrides have been specified on the command-line, then
++ * these values are copied into the main storage variables.
++ */
++void
++m6809_override_options (void)
++{
++	/* Handle -mfar-code-page */
++	if (far_code_page_option == 0)
++		far_code_page_option = "__default_code_page";
++	strcpy (far_code_page, far_code_page_option);
++
++	/* Handle -mcode-section, -mdata-section, and -mbss-section */
++	if (code_section_ptr != 0)
++		sprintf (code_section_op, "\t.area\t%s", code_section_ptr);
++	if (data_section_ptr != 0)
++		sprintf (data_section_op, "\t.area\t%s", data_section_ptr);
++	if (bss_section_ptr != 0)
++		sprintf (bss_section_op, "\t.area\t%s", bss_section_ptr);
++
++	/* Handle -mcode-bank */
++	if (code_bank_option != 0)
++		sprintf (default_code_bank_name, "%s", code_bank_option);
++
++	/* Handle -mabi-version or -mno-reg-args */
++	if (m6809_abi_version_ptr != 0)
++	{
++		if (!strcmp (m6809_abi_version_ptr, "stack"))
++			m6809_abi_version = M6809_ABI_VERSION_STACK;
++		else if (!strcmp (m6809_abi_version_ptr, "regs"))
++			m6809_abi_version = M6809_ABI_VERSION_REGS;
++		else if (!strcmp (m6809_abi_version_ptr, "bx"))
++			m6809_abi_version = M6809_ABI_VERSION_BX;
++		else if (!strcmp (m6809_abi_version_ptr, "latest"))
++			m6809_abi_version = M6809_ABI_VERSION_LATEST;
++		else
++			m6809_abi_version = atoi (m6809_abi_version_ptr);
++	}
++
++	/* The older -mno-reg-args option is deprecated, and treated
++	as -mabi=stack. */
++	if (!TARGET_REG_ARGS)
++   {
++      warning (WARNING_OPT "-mno-reg-args deprecated; use -mabi=stack instead.");
++      m6809_abi_version = M6809_ABI_VERSION_STACK;
++   }
++
++	/* -fexceptions is unsupported */
++	flag_exceptions = 0;
++	flag_non_call_exceptions = 0;
++	flag_unwind_tables = 0;
++}
++
++
++/**
++ * Output prefix that directs the assembler to use a direct-mode
++ * instruction if globally enabled, address is a symbol, and symbol
++ * has been marked as in direct page.  Also, never do this if
++ * using the indirect mode. */
++void
++print_direct_prefix (FILE * file, rtx addr)
++{
++	if (TARGET_DIRECT &&
++       (GET_CODE (addr) == SYMBOL_REF) && 
++       SYMBOL_REF_FLAG (addr) &&
++       check_direct_prefix_flag)
++   {
++      putc ('*', file);
++   }
++}
++
++
++/** Prints an operand (that is not an address) in assembly from RTL. */
++void
++print_operand (FILE * file, rtx x, int code)
++{
++	if (REG_P (x)) {
++		/* gcc currently allocates the entire 16-bit 'd' register
++		 * even when it only needs an 8-bit value.  So here it
++		 * is tricked into printing only the lower 8-bit 'b'
++		 * register into the assembly output.
++		 *
++		 * Eventually gcc should be modified to allocate a/b
++		 * independently and this hack can be removed.
++		 *
++		 * Occasionally, we may want to do an operation using
++		 * the 'a' register instead of 'b'; use the 'A' code
++		 * to specify that.
++		 */
++		if (code == 'A')
++			fputs ("a", file);
++		else if ((BYTE_MODE (x)) && (REGNO (x) == HARD_D_REGNUM))
++			fputs ("b", file);
++		else if (M_REG_P (x) && code == 'L')
++			/* Soft registers can be treated like memory and accessed
++			 * at a particular offset. TODO : handle 'W' */
++			fputs (reg_names[REGNO (x)+1], file);
++		else
++			fputs (reg_names[REGNO (x)], file);
++	}
++
++	else if (MEM_P (x)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (x));
++		if (code == 'L') {	/* LSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 1);
++		}
++		else if (code == 'M') { /* MSH of word address */
++			if (GET_CODE (XEXP (x, 0)) == MEM)
++			{
++				/* Offseting an indirect addressing mode is not supported */
++				error ("expression too complex for 6809 (offset indirect mode)");
++				debug_rtx (x);
++			}
++			else
++				x = adjust_address (x, QImode, 0);
++		}
++		else if (code == 'W') { /* least significant half of 32-bit */
++			x = adjust_address (x, HImode, 2);
++		}
++
++		pic_ok_for_addr_p = (code != 'C');
++		output_address (XEXP (x, 0));
++	}
++
++	else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode) {
++		union { double d; int i[2]; } u;
++		u.i[0] = CONST_DOUBLE_LOW (x);
++		u.i[1] = CONST_DOUBLE_HIGH (x);
++		fprintf (file, "#%#9.9g", u.d);
++	}
++
++	else if (code == 'R') {
++		fprintf (file, "%s", 
++			m6809_get_regs_printable (INTVAL (x)));
++	}
++
++	else {
++		if (code == 'L') {	/* LSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, (INTVAL(x) & 0xff));
++		}
++		else if (code == 'M') {	/* MSH of word address */
++			x = gen_rtx_CONST_INT (VOIDmode, ((INTVAL(x) >> 8) & 0xff));
++		}
++
++		putc ('#', file);
++		output_addr_const (file, x);
++	}
++}
++
++
++/** Prints an address operand to assembler from its RTL representation. */
++void
++print_operand_address (FILE *file, rtx addr)
++{
++	register rtx base = 0;
++	register rtx offset = 0;
++	int regno;
++	int indirect_flag = 0;
++
++	check_direct_prefix_flag = 0;
++
++	/*** check for indirect addressing ***/
++	if (MEM_P (addr)) {
++		last_mem_size = GET_MODE_SIZE (GET_MODE (addr));
++		addr = XEXP (addr, 0);
++		if (pic_ok_for_addr_p)
++		{
++			indirect_flag = 1;
++			fprintf (file, "[");
++		}
++	}
++
++
++	switch (GET_CODE (addr)) {
++		case REG:
++			regno = REGNO (addr);
++			fprintf (file, ",%s", reg_names[regno]);
++			break;
++
++		case PRE_DEC:
++			regno = REGNO (XEXP (addr, 0));
++			fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++			fprintf (file, "%s", reg_names[regno]);
++			break;
++
++		case POST_INC:
++			regno = REGNO (XEXP (addr, 0));
++			fprintf (file, ",%s", reg_names[regno]);
++			fputs (((last_mem_size == 1) ? "+" : "++"), file);
++			break;
++
++		case PLUS:
++			base = XEXP (addr, 0);
++			if (MEM_P (base))
++				base = XEXP (base, 0);
++
++			offset = XEXP (addr, 1);
++			if (MEM_P (offset))
++				offset = XEXP (offset, 0);
++
++			if ((CONSTANT_ADDRESS_P (base)) && (CONSTANT_ADDRESS_P (offset))) {
++				if (!indirect_flag)
++					check_direct_prefix_flag = 1;
++				output_addr_const (file, base);
++				check_direct_prefix_flag = 0;
++				fputs ("+", file);
++				output_addr_const (file, offset);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (base)) && (A_REG_P (offset))) {
++				output_addr_const (file, base);
++				fprintf (file, ",%s", reg_names[REGNO (offset)]);
++			}
++
++			else if ((CONSTANT_ADDRESS_P (offset)) && (A_REG_P (base))) {
++				output_addr_const (file, offset);
++				fprintf (file, ",%s", reg_names[REGNO (base)]);
++			}
++
++			/*** accumulator offset ***/
++			else if (((D_REG_P (offset)) || (Q_REG_P (offset)))
++			&& (A_REG_P (base))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (offset)], reg_names[REGNO (base)]);
++			}
++
++			else if (((D_REG_P (base)) || (Q_REG_P (base)))
++			&& (A_REG_P (offset))) {
++				fprintf (file, "%s,%s",
++				reg_names[REGNO (base)], reg_names[REGNO (offset)]);
++			}
++
++			else if (GET_CODE (base) == PRE_DEC) {
++				regno = REGNO (XEXP (base, 0));
++				fputs (((last_mem_size == 1) ? ",-" : ",--"), file);
++				fprintf (file, "%s", reg_names[regno]);
++			}
++
++			else
++				abort ();
++
++			break;
++
++   default:
++		/* Set this global before calling output_addr_const() */
++		if (!indirect_flag)
++			check_direct_prefix_flag = 1;
++
++		/* When printing a SYMBOL_REF in PIC mode, do not print the leading
++		 * '#' and follow it by ',pcr' to enable relative addressing. */
++		if (flag_pic && pic_ok_for_addr_p && GET_CODE (addr) == SYMBOL_REF)
++		{
++			ASM_OUTPUT_SYMBOL_REF (file, addr);
++			fputs (",pcr", file);
++			pic_ok_for_addr_p = 1;
++		}
++		else
++		{
++      	output_addr_const (file, addr);
++		}
++
++		check_direct_prefix_flag = 0;
++      break;
++	}
++
++	if (indirect_flag)
++		fprintf (file, "]");
++}
++
++/*-------------------------------------------------------------------
++    Update the CC Status
++---------------------------------------------------------------------
++   Set the cc_status for the results of an insn whose pattern is EXP.
++   We assume that jumps don't affect the condition codes.
++   All else, clobbers the condition codes, by assumption.
++
++   We assume that ALL add, minus, etc. instructions effect the condition
++   codes.
++-------------------------------------------------------------------*/
++void
++notice_update_cc (rtx exp, rtx insn ATTRIBUTE_UNUSED)
++{
++	int src_code;
++	int dst_code;
++
++	/*** recognize SET insn's ***/
++	if (GET_CODE (exp) == SET)
++	{
++		src_code = GET_CODE (SET_SRC (exp));
++		dst_code = GET_CODE (SET_DEST (exp));
++
++		/* Jumps do not alter the cc's.  */
++		if (SET_DEST (exp) == pc_rtx)
++			return;
++
++		/* Moving one register into another register (tfr):
++		Doesn't alter the cc's.  */
++		if (REG_P (SET_DEST (exp)) && (REG_P (SET_SRC (exp))))
++			return;
++
++		/* Moving memory into a register (load): Sets cc's. */
++		if (REG_P (SET_DEST (exp)) && src_code == MEM) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Moving register into memory (store): Sets cc's. */
++		if (dst_code == MEM && REG_P (SET_SRC (exp))) {
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			cc_status.flags |= CC_NO_OVERFLOW;
++			return;
++		}
++
++		/* Function calls clobber the cc's.  */
++		else if (GET_CODE (SET_SRC (exp)) == CALL) {
++			CC_STATUS_INIT;
++			return;
++		}
++
++		/* Tests and compares set the cc's in predictable ways.  */
++		else if (SET_DEST (exp) == cc0_rtx)
++		{
++			cc_status.flags = 0;
++			cc_status.value1 = SET_SRC (exp);
++			cc_status.value2 = SET_DEST (exp);
++			return;
++		}
++
++		else if (A_REG_P (SET_DEST (exp)))
++		{
++			CC_STATUS_INIT;
++			return;
++		}
++
++		else
++		{
++			/* Certain instructions affect the condition codes. */
++			switch (src_code)
++			{
++				case PLUS:
++				case MINUS:
++				case NEG:
++				case ASHIFT:
++					/* These instructions set the condition codes,
++					 * and may modify the V bit. */
++					cc_status.flags |= CC_NO_OVERFLOW;
++					/* FALLTHRU */
++
++				case AND:
++				case IOR:
++				case XOR:
++				case ASHIFTRT:
++				case LSHIFTRT:
++					/* These instructions set the condition codes,
++					 * but cannot overflow (V=0). */
++					cc_status.value1 = SET_SRC (exp);
++					cc_status.value2 = SET_DEST (exp);
++					break;
++
++				default:
++					/* Everything else is clobbered */
++					CC_STATUS_INIT;
++			}
++			return;
++		}
++	} /* SET */
++
++	else if (GET_CODE (exp) == PARALLEL
++		&& GET_CODE (XVECEXP (exp, 0, 0)) == SET)
++	{
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
++			return;
++		if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
++		{
++			CC_STATUS_INIT;
++			cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
++			return;
++		}
++	}
++
++	/*** default action if we haven't recognized something
++	and returned earlier ***/
++	CC_STATUS_INIT;
++}
++
++
++/** Returns nonzero if the expression EXP can be implemented using one
++ * of the 6809's single operand instructions. */
++int
++m6809_single_operand_operator (rtx exp)
++{
++	rtx op1;
++	HOST_WIDE_INT val;
++	enum rtx_code code;
++
++	debug_rtx(exp);
++
++	code = GET_CODE (exp);
++
++	/* Unary operators always qualify */
++	switch (code)
++	{
++		case NEG:
++		case NOT:
++			return 1;
++
++		default:
++			break;
++	}
++
++	/* Binary operators can only qualify if the second
++	 * argument is a CONST_INT of certain value. */
++	op1 = XEXP (exp, 1);
++	if (GET_CODE (op1) != CONST_INT)
++		return 0;
++	val = INTVAL (op1);
++	switch (code)
++	{
++		case PLUS:
++		case MINUS:
++			if (val == -1 || val == 1)
++				return 1;
++			break;
++
++		case ASHIFT:
++		case ASHIFTRT:
++		case LSHIFTRT:
++		case ROTATE:
++		case ROTATERT:
++			if (val == 1)
++				return 1;
++			break;
++
++		default:
++			break;
++	}
++
++	return 0;
++}
++
++
++/** Return a bitarray of the hard registers which are used by a function. */
++unsigned int
++m6809_get_live_regs (void)
++{
++	unsigned int regs = 0;
++	int regno;
++
++	if (frame_pointer_needed)
++		regs |= (1 << HARD_FRAME_POINTER_REGNUM);
++
++	for (regno = HARD_X_REGNUM; regno <= HARD_U_REGNUM; regno++)
++		if (df_regs_ever_live_p (regno) && ! call_used_regs[regno])
++			regs |= (1 << regno);
++
++	return regs;
++}
++
++
++/** Return a printable version of a list of hard registers, suitable
++ * for use in a PSHx or PULx insn. */
++const char *
++m6809_get_regs_printable (unsigned int regs)
++{
++	static char list[64];
++	char *listp = list;
++	unsigned int regno;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++		if ((regs & (1 << regno)) && !S_REGNO_P (regno))
++			listp += sprintf (listp,
++				(listp == list) ? "%s" : ",%s", reg_names[regno]);
++
++	return list;
++}
++
++
++/** Return the total number of bytes covered by a set of hard registers. */
++unsigned int
++m6809_get_regs_size (unsigned int regs)
++{
++	unsigned int regno;
++	unsigned int size = 0;
++
++	for (regno=0; regno < FIRST_PSEUDO_REGISTER; regno++)
++	{
++		/* Only count register in the given register set */
++		if (REGSET_CONTAINS_P (regno, regs))
++		{
++			/* Add 1 or 2 byte, depending on the size of the register.
++			 * Since 'D' may be in both sets, check for WORD_REGSET first. */
++			if (REGSET_CONTAINS_P(regno, WORD_REGSET))
++				size += 2;
++			else if (REGSET_CONTAINS_P(regno, BYTE_REGSET))
++				size++;
++		}
++	}
++	return size;
++}
++
++
++/* Given the target of call instruction in X,
++ * return the tree node that contains the function declaration for
++ * that target.
++ *
++ * If the rtx or the tree do not appear valid for any reason,
++ * then return NULL_TREE.
++ */
++static tree call_target_decl (rtx x)
++{
++   tree decl;
++
++	/* Make sure the target is really a MEM. */
++	if (!x || !MEM_P (x))
++		return NULL_TREE;
++
++	/* Make sure the address is a SYMBOL_REF. */
++	x = XEXP (x, 0);
++	if (!x || (GET_CODE (x) != SYMBOL_REF))
++		return NULL_TREE;
++
++	/* Get the declaration of this symbol */
++	decl = SYMBOL_REF_DECL (x);
++
++	/* Make sure the declaration is really a function. */
++	if (!decl || (TREE_CODE(decl) != FUNCTION_DECL))
++		return NULL_TREE;
++
++   return decl;
++}
++
++
++/** Returns nonzero if a function, whose declaration is in DECL,
++ * was declared to have the attribute given by ATTR_NAME. */
++int
++m6809_function_has_type_attr_p (tree decl, const char *attr_name)
++{
++	tree type;
++
++	type = TREE_TYPE (decl);
++	return lookup_attribute (attr_name, TYPE_ATTRIBUTES (type)) != NULL;
++}
++
++
++
++/** Returns nonzero if the current function was declared to have the
++ * attribute given by ATTR_NAME. */
++int
++m6809_current_function_has_type_attr_p (const char *attr_name)
++{
++	return m6809_function_has_type_attr_p (current_function_decl, attr_name);
++}
++
++
++/** Return nonzero if the current function has no return value. */
++int
++m6809_current_function_is_void (void)
++{
++   return (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (current_function_decl))));
++}
++
++
++/** Get the value of a declaration's 'bank', as set by the 'bank'
++ * attribute.  If no bank was declared, it returns NULL by default. */
++const char *
++m6809_get_decl_bank (tree decl)
++{
++	tree attr;
++
++	/* Lookup the 'bank' attribute.  If it does not exist, then
++	 * return NULL */
++	attr = lookup_attribute ("bank", DECL_ATTRIBUTES (decl));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* Make sure it has a value assigned to it */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "banked function did not declare a bank number");
++		return NULL;
++	}
++
++	/* Return the bank name */
++	attr = TREE_VALUE (attr);
++	return TREE_STRING_POINTER (attr);
++}
++
++
++void
++m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl)
++{
++	/* Check the function declaration for special properties.
++	 *
++	 * If the function was declare with __attribute__((bank)), output
++	 * assembler definitions to force the function to go into the named
++	 * bank.
++	 */
++	const char *bank_name = m6809_get_decl_bank (decl);
++	if (bank_name != NULL)
++	{
++		fprintf (asm_out_file, "\n");
++
++		/* Declare __self_bank as a local assembler value that denotes
++		 * which bank the current function is in.  This is required only
++		 * when the bank actually changes. */
++		if (strcmp (bank_name, current_bank_name))
++		{
++			fprintf (asm_out_file, "__self_bank\t.equ\t%s\n", bank_name);
++			strcpy (current_bank_name, bank_name);
++		}
++
++		/* Declare a global assembler value that denotes which bank the
++		 * named function is in. */
++		fprintf (asm_out_file, "__%s_bank\t.gblequ\t%s\n", name, bank_name);
++
++		/* Force the current function into a new area */
++		fprintf (asm_out_file, "\t.bank\tbank_%s (FSFX=_%s)\n",
++			bank_name, bank_name);
++		fprintf (asm_out_file, "\t.area\tbank_%s (BANK=bank_%s)\n",
++			bank_name, bank_name);
++	}
++
++	/* Emit the label for the function's name */
++	ASM_OUTPUT_LABEL (asm_out_file, name);
++}
++
++#if 0
++/**
++ * Handle pragmas.  Note that only the last branch pragma seen in the 
++ * source has any affect on code generation.  
++ */
++
++#define BAD_PRAGMA(msgid, arg) \
++	do { warning (WARNING_OPT msgid, arg); return -1; } while (0)
++
++static int
++pragma_parse (const char *name, tree *sect)
++{
++  tree s, x;
++
++  if (pragma_lex (&x) != CPP_OPEN_PAREN)
++    BAD_PRAGMA ("missing '(' after '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&s) != CPP_STRING)
++    BAD_PRAGMA ("missing section name in '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_CLOSE_PAREN)
++    BAD_PRAGMA ("missing ')' for '#pragma %s' - ignored", name);
++
++  if (pragma_lex (&x) != CPP_EOF)
++    warning (WARNING_OPT "junk at end of '#pragma %s'", name);
++
++  *sect = s;
++  return 0;
++}
++
++
++/*
++ * Handle #pragma section.
++ * This is deprecated; code should use __attribute__(section("name"))
++ * instead.
++ */
++void pragma_section (cpp_reader *pfile ATTRIBUTE_UNUSED)
++{
++	tree sect;
++
++	if (pragma_parse ("section", &sect))
++		return;
++
++	snprintf (code_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++	snprintf (data_section_op, 6+TREE_STRING_LENGTH (sect),
++		".area\t%s", TREE_STRING_POINTER (sect));
++
++	/* Mark a flag that sections have changed.  Upon emitting another
++	 * declaration, the new .area directive will be written. */
++	section_changed++;
++}
++#endif
++
++/**
++ * Check a `double' value for validity for a particular machine mode.
++ * Called by the CHECK_FLOAT_VALUE() machine-dependent macro.
++ */
++int
++check_float_value (enum machine_mode mode, double *d, int overflow)
++{
++	if (mode == SFmode) {
++		if (*d > 1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = 1.7014117331926443e+38;
++		}
++		else if (*d < -1.7014117331926443e+38) {
++			error("magnitude of constant too large for `float'");
++			*d = -1.7014117331926443e+38;
++		}
++		else if ((*d > 0) && (*d < 2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++		else if ((*d < 0) && (*d > -2.9387358770557188e-39)) {
++			warning(WARNING_OPT "`float' constant truncated to zero");
++			*d = 0.0;
++		}
++	}
++	return overflow;
++}
++
++
++
++/** Declare that the target supports named output sections. */
++bool m6809_have_named_section = (bool)1;
++
++
++/** Write to the assembler file a directive to place
++ * subsequent objects to a different section in the
++ * object file.  ASxxxx uses the "area" directive for
++ * this purpose.  It does not however support generalized
++ * alignment, and can only place items on an odd/even
++ * boundary. */
++void
++m6809_asm_named_section (
++	const char *name, 
++	unsigned int flags ATTRIBUTE_UNUSED,
++	tree decl)
++{
++	fprintf (asm_out_file, "\n\t.area\t%s\n", name);
++}
++
++
++enum reg_class
++m6809_preferred_reload_class (rtx x, enum reg_class regclass)
++{
++	/* Check cases based on type code of rtx */
++	switch (GET_CODE(x))
++	{
++		/*
++		 * Observation, 2015-07-19, William Astle
++		 *
++		 * The original comparison for range for 16 bits was wrong, adding 0x80
++		 * instead of 0x8000. Replaced both 8 bit and 16 bit comparisions with
++		 * a more straight forward range comparison - excessive cleverness isn't
++		 * really required here.
++		 */    
++		case CONST_INT:
++		   /* Constants that can fit into 1 byte should be
++			 * loaded into a Q_REGS reg */
++			if ((INTVAL(x) >= -128 && INTVAL(x) <= 127) &&
++//			if (((unsigned) (INTVAL(x) + 0x80) < 0x100) && 
++  				 (regclass > A_REGS))
++      		return Q_REGS;
++
++			/* 16-bit constants should be loaded into A_REGS
++			 * when possible.  gcc may already require A_REGS
++			 * or D_REGS for certain types of instructions.
++			 * This case applies mostly to simple copy operations
++			 * to/from memory when any register will do, but
++			 * it's best to avoid using D register since it is
++			 * needed for other things.
++			 */
++			else if ((INTVAL(x) >= -32768 && INTVAL(x) <= 32767) &&
++//			else if (((unsigned) (INTVAL(x) + 0x80) < 0x10000) &&
++  				 (regclass > A_REGS))
++      		return A_REGS;
++			break;
++
++		case SYMBOL_REF:
++		case LABEL_REF:
++			/* Addresses should always be loaded into A_REGS */
++			if (regclass >= A_REGS)
++				return (A_REGS);
++
++		default:
++			break;
++	}
++
++	/* Check cases based on mode of rtx */
++   if ((GET_MODE(x) == QImode) && (regclass != A_REGS))
++      return Q_REGS;
++
++	/* Default: return whatever class reload suggested */
++   return regclass;
++}
++
++
++/**
++ * Check a new declaration for the "section" attribute.
++ * If it exists, and the target section is "direct", then mark
++ * the declaration (in RTL) to indicate special treatment.
++ * When the variable is referenced later, we test for this flag
++ * and can emit special asm text to force the assembler to use
++ * short instructions.
++ */
++static void
++m6809_encode_section_info (tree decl, rtx rtl, int new_decl_p ATTRIBUTE_UNUSED)
++{
++   tree attr, id;
++   const char *name;
++   const char *decl_name;
++
++   /* We only care about variable declarations, not functions */
++   if (TREE_CODE (decl) != VAR_DECL)
++      return;
++
++	/* For debugging purposes only; grab the decl's name */
++   decl_name = IDENTIFIER_POINTER (DECL_NAME (decl));
++
++	/* Give up if the decl doesn't have any RTL */
++   if (!DECL_RTL (decl))
++      return;
++
++	/* See if it has a section attribute */
++   attr = lookup_attribute ("section", DECL_ATTRIBUTES (decl));
++   if (!attr)
++      return;
++
++	/* See if the section attribute has a value */
++   id = TREE_VALUE (TREE_VALUE (attr));
++   if (!id)
++      return;
++   name = TREE_STRING_POINTER (id);
++   if (!name)
++      return;
++
++	/* See if the value is 'direct'.  If so, mark it. */
++   if (!strcmp (name, "direct"))
++      SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl), 0)) = 1;
++}
++
++
++/**
++ * Output code to perform a complex shift, for which there is no
++ * direct support in the instruction set.
++ *
++ * shift1 is an instruction pattern for performing a 1-bit modification.
++ * This code wraps that pattern in a loop to perform the shift N times,
++ * where N is given by the address register in operands[2].
++ *
++ * To support 16-bit shifts, shift2 can also be provided: it is
++ * a second instruction to be included in the loop.  8-bit shift
++ * insns will pass NULL here.
++ *
++ * The insn length of shift1/shift2 is assumed to be 1 byte,
++ * which works in all of the cases it is needed so far.
++ */
++static void
++m6809_gen_register_shift (
++		rtx *operands,
++		const char *shift1,
++		const char *shift2 )
++{
++	char beq_pattern[32];
++   char bra_pattern[32];
++
++	int shiftlen = (shift1 && shift2) ? 2 : 1;
++	int cmplen = (REGNO (operands[2]) == HARD_X_REGNUM) ? 3 : 4;
++
++	int beq_offset = 2 + shiftlen + 2;
++	int bra_offset = shiftlen + 2 + cmplen + 2;
++
++	sprintf (beq_pattern, "beq\t.+%d", beq_offset);
++	sprintf (bra_pattern, "bra\t.-%d", bra_offset);
++
++	output_asm_insn ("pshs\t%2", operands);
++	output_asm_insn ("lea%2\t-1,%2", operands);
++   output_asm_insn ("cmp%2\t#-1", operands);
++   output_asm_insn (beq_pattern, operands);
++	if (shift1)
++		output_asm_insn (shift1, operands);
++	if (shift2)
++		output_asm_insn (shift2, operands);
++	output_asm_insn (bra_pattern, operands);
++	output_asm_insn ("puls\t%2", operands);
++}
++
++
++/** Generate RTL for the upper 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_high (rtx r)
++{
++   unsigned char v = (INTVAL (r) >> 8) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL for the lower 8-bits of a 16-bit constant. */
++rtx
++gen_rtx_const_low (rtx r)
++{
++   unsigned char v = INTVAL (r) & 0xFF;
++	signed char s = (signed char)v;
++   return gen_int_mode (s, QImode);
++}
++
++
++/** Generate RTL to allocate/free bytes on the stack.
++ * CODE is given as MINUS when allocating and PLUS when freeing,
++ * to match the semantics of a downward-growing stack.  SIZE
++ * is always given as a positive integer.
++ */
++static rtx
++gen_rtx_stack_adjust (enum rtx_code code, int size)
++{
++	if (size <= 0)
++		return NULL_RTX;
++
++	if (code == MINUS)
++		size = -size;
++
++	return gen_rtx_SET (Pmode, stack_pointer_rtx, 
++		gen_rtx_PLUS (Pmode, stack_pointer_rtx,
++			gen_int_mode (size, HImode)));
++}
++
++
++/** Generate RTL to push/pop a set of registers. */
++rtx
++gen_rtx_register_pushpop (int op, int regs)
++{
++	rtx nregs = gen_int_mode (regs, QImode);
++	
++	if (op == UNSPEC_PUSH_RS)
++		return gen_register_push (nregs);
++	else
++		return gen_register_pop (nregs);
++}
++
++
++/* Given a register set REGS, where the bit positions correspond to
++ * hard register numbers, return another bitmask that represents the
++ * order in which those registers would be pushed/popped.
++ * Registers that are pushed first have higher bit positions.
++ * The pop order is just the reverse bitmask.
++ * These values are the same as the bitmasks actually used in the
++ * machine instructions. */
++static unsigned int
++register_push_order (int regs)
++{
++	unsigned int order = 0;
++
++	if (REGSET_CONTAINS_P (HARD_PC_REGNUM, regs))
++		order |= 0x80;
++	if (REGSET_CONTAINS_P (HARD_U_REGNUM, regs))
++		order |= 0x40;
++	if (REGSET_CONTAINS_P (HARD_Y_REGNUM, regs))
++		order |= 0x20;
++	if (REGSET_CONTAINS_P (HARD_X_REGNUM, regs))
++		order |= 0x10;
++	if (REGSET_CONTAINS_P (HARD_DP_REGNUM, regs))
++		order |= 0x8;
++	if (REGSET_CONTAINS_P (HARD_B_REGNUM, regs))
++		order |= 0x4;
++	if (REGSET_CONTAINS_P (HARD_A_REGNUM, regs))
++		order |= 0x2;
++	if (REGSET_CONTAINS_P (HARD_CC_REGNUM, regs))
++		order |= 0x1;
++
++	if (REGSET_CONTAINS_P (HARD_D_REGNUM, regs))
++		order |= (0x4 | 0x2);
++	return order;
++}
++
++
++/* Returns nonzero if two consecutive push or pop instructions,
++ * as determined by the OP, can be merged into a single instruction.
++ * The first instruction in the sequence pushes/pops REGS1; the
++ * second applies to REGS2.
++ *
++ * If true, the resulting instruction can use (regs1 | regs2)
++ * safely.
++ */
++int
++m6809_can_merge_pushpop_p (int op, int regs1, int regs2)
++{
++	/* Register sets must not overlap */
++	if (regs1 & regs2)
++		return 0;
++
++	if (op == UNSPEC_PUSH_RS)
++		return (register_push_order (regs1) > register_push_order (regs2));
++	else if (op == UNSPEC_POP_RS)
++		return (register_push_order (regs1) < register_push_order (regs2));
++	else
++		return 0;
++}
++
++
++/** Emit instructions for making a library call.
++ * MODE is the mode of the operation.
++ * NAME is the library function name.
++ * OPERANDS is the rtx array provided by the recognizer.
++ * COUNT is the number of input operands to the call, and
++ * should be 1 for a unary op or 2 for a binary op.
++ */
++void
++emit_libcall_insns (enum machine_mode mode, 
++	const char *name, 
++	rtx *operands,
++	int count)
++{
++	/* Generate an rtx for the call target. */
++	rtx symbol = gen_rtx_SYMBOL_REF (Pmode, name);
++
++	/* Emit the library call.  Slightly different based
++	on the number of operands */
++	if (count == 2)
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			2, operands[1], mode, operands[2], mode);
++	else
++		emit_library_call (symbol, LCT_NORMAL, mode,
++			1, operands[1], mode);
++
++	/* The library call is expected to put its result
++	in LIBCALL_VALUE, so need to copy it into the destination. */
++	emit_move_insn (operands[0], LIBCALL_VALUE(mode));
++}
++
++
++/**
++ * A small helper function that writes out a single branch instruction.
++ * OPCODE is the short name, e.g. "ble".
++ * OPERANDS has the rtx for the target label.
++ * LONG_P is nonzero if we are emitting a long branch, and need to
++ * prepend an 'l' to the opcode name.
++ */
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p)
++{
++	char pattern[64];
++	sprintf (pattern, "%s%s\t%%l0", long_p ? "l" : "", opcode);
++	output_asm_insn (pattern, operands);
++}
++
++/**
++ * Output a branch/conditional branch insn of the proper
++ * length.  code identifies the particular branch insn.
++ * operands holds the branch target in operands[0].
++ * length says what the size of this insn should be.
++ * Based on the length, we know whether it should be a
++ * short (8-bit) or long (16-bit) branch.
++ */
++const char *
++output_branch_insn (enum rtx_code code, rtx *operands, int length)
++{
++	int shortform; 
++
++	/* Decide whether or not to use the long or short form.
++	 * Calculate automatically based on insn lengths. */
++   shortform = ((length > 2) ? 0 : 1);
++
++	/* Determine the proper opcode.
++	 * Use the short (2-byte) opcode if the target is within
++	 * reach.  Otherwise, use jmp (3-byte opcode), unless
++	 * compiling with -fpic, in which case we'll need to use
++	 * lbra (4-byte opcode).
++	 */
++	switch (code)
++	{
++		case LABEL_REF: 
++			if (shortform)
++				output_branch_insn1 ("bra", operands, 0);
++			else if (flag_pic)
++				output_branch_insn1 ("bra", operands, 1);
++			else
++				output_branch_insn1 ("jmp", operands, 0);
++			break;
++		case EQ:
++			output_branch_insn1 ("beq", operands, !shortform);
++			break;
++		case NE:
++			output_branch_insn1 ("bne", operands, !shortform);
++			break;
++		case GT:
++			output_branch_insn1 ("bgt", operands, !shortform);
++			break;
++		case GTU:
++			output_branch_insn1 ("bhi", operands, !shortform);
++			break;
++		case LT:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("blt", operands, !shortform);
++			}
++			break;
++		case LTU:
++			output_branch_insn1 ("blo", operands, !shortform);
++			break;
++		case GE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bpl", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("bge", operands, !shortform);
++			}
++			break;
++		case GEU:
++			output_branch_insn1 ("bhs", operands, !shortform);
++			break;
++		case LE:
++			if (cc_prev_status.flags & CC_NO_OVERFLOW)
++			{
++				output_branch_insn1 ("bmi", operands, !shortform);
++				output_branch_insn1 ("beq", operands, !shortform);
++			}
++			else
++			{
++				output_branch_insn1 ("ble", operands, !shortform);
++			}
++			break;
++		case LEU:
++			output_branch_insn1 ("bls", operands, !shortform);
++			break;
++		default:
++			abort();
++			break;
++	}
++	return "";
++}
++
++
++/** Returns the "cost" of an RTL expression.
++ * In general, the expression "COSTS_N_INSNS(1)" is used to represent
++ * the cost of a fast 8-bit arithmetic instruction that operates on
++ * a reg/mem or a reg/immed.  Other costs are relative to this.
++ *
++ * Notes:
++ * - The cost of a REG is always zero; this cannot be changed.
++ *
++ * - On the 6809, instructions on two registers will nearly always take
++ *   longer than those that operate on a register and a constant/memory,
++ *   because of the way the instruction set is structured.
++ *
++ * TODO: multiply HImode by 2 should be done via shifts, instead of add.
++ */
++static bool
++m6809_rtx_costs (rtx X, int code, int outer_code ATTRIBUTE_UNUSED,
++	int *total, bool speed)
++{
++	int has_const_arg = 0;
++	HOST_WIDE_INT const_arg;
++	enum machine_mode mode;
++	int nargs = 1;
++	rtx op0, op1;
++
++	/* Data RTXs return a value between 0-3, depending on complexity.
++	All of these are less than COSTS_N_INSNS(1). */
++	switch (code)
++	{
++		case CC0:
++		case PC:
++			*total = 0;
++			return true;
++
++ 		case CONST_INT:
++    		if (X == const0_rtx)
++			{
++				*total = 0;
++				return true;
++			}
++			else if ((unsigned) INTVAL (X) < 077) 
++			{
++				*total = 1;
++				return true;
++			}
++			else
++			{
++				*total = 2;
++				return true;
++			}
++
++ 		case LABEL_REF: case CONST:
++   		*total = 2;
++			return true;
++
++ 		case SYMBOL_REF:
++			/* References to memory are made cheaper if they have
++			 * the 'direct' mode attribute set */
++			*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++			return true;
++
++		case MEM:
++			/* See what form of address was given */
++			X = XEXP (X, 0);
++			switch (GET_CODE (X))
++			{
++ 				case SYMBOL_REF:
++					*total = (SYMBOL_REF_FLAG (X)) ? 1 : 2;
++					break;
++
++				case CONST_INT:
++					*total = 2;
++					break;
++
++				case MEM:
++					*total = COSTS_N_INSNS (1) + 2;
++					break;
++
++				default:
++					break;
++			}
++			return true;
++
++ 		case CONST_DOUBLE:
++			/* TODO : not sure about this value. */
++   		*total = 3;
++			return true;
++
++		default:
++			break;
++	}
++
++	/* Decode the rtx */
++	mode = GET_MODE (X);
++	op0 = XEXP (X, 0);
++	op1 = XEXP (X, 1);
++
++	/* We don't implement anything in SImode or greater. */
++	if (GET_MODE_SIZE (mode) >= GET_MODE_SIZE (SImode))
++	{
++		*total = COSTS_N_INSNS (100);
++		return true;
++	}
++
++	/* Figure out if there is a constant argument, and its value. */
++	if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
++		|| GET_RTX_CLASS (code) == RTX_COMM_ARITH)
++	{
++		nargs = 2;
++		if (GET_CODE (op1) == CONST_INT)
++		{
++			has_const_arg = 1;
++			const_arg = INTVAL (op1);
++		}
++	}
++
++	/* Penalize a reg/reg operation by adding MEMORY_MOVE_COST,
++	 * Ignore soft registers, since these are really in memory.
++	 *
++	 * TODO: penalize HImode reg/reg for most operations, except maybe
++	 * additions since index registers allow for that.
++	 *
++	 * TODO: shifts by constant N do not always require N instructions;
++	 * some of this can be done cheaper.  The number of actual insns can be
++	 * predicted well.
++	 */
++	if (nargs == 2 && REAL_REG_P (op0) && REAL_REG_P (op1))
++	{
++		*total = MEMORY_MOVE_COST (mode, Q_REGS, 0);
++	}
++	else
++	{
++		*total = 0;
++	}
++
++	/* Operator RTXs are counted as COSTS_N_INSNS(N), where N is
++	the estimated number of actual machine instructions needed to
++	perform the computation.  Some small adjustments are made since
++	some "instructions" are more complex than others. */
++	switch (code)
++	{
++		case PLUS: case MINUS: case COMPARE:
++			/* 6809 handles these natively in QImode, and in HImode as long
++			 * as operand 1 is constant. */
++			if (mode == QImode || (mode == HImode && has_const_arg))
++				*total += COSTS_N_INSNS (1);
++			else 
++				*total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
++
++			/* -1, 0, and 1 can be done using inherent instructions
++			 * for PLUS and MINUS in QImode, so don't add extra cost. */
++  			if (has_const_arg
++				&& (mode == QImode || mode == HImode)
++				&& (const_arg == -1 || const_arg == 0 || const_arg == 1)
++				&& (code == PLUS || code == MINUS))
++			{
++				return true;
++			}
++			break;
++
++		case AND: case IOR: case XOR:
++		case NEG: case NOT:
++			/* 6809 handles these natively in QImode, but requires
++			 * splitting in HImode.   Treat these as 2 insns. */
++			*total += COSTS_N_INSNS (1) * GET_MODE_SIZE (mode);
++			break;
++
++  		case ASHIFT: case ASHIFTRT: case LSHIFTRT:
++  		case ROTATE: case ROTATERT:
++			/* 6809 can do shift/rotates of a QImode by a constant in
++			 * 1 insn times the shift count, or in HImode by a constant 
++			 * by splitting to 2 insns.
++			 *
++			 * Shift by a nonconstant will take significantly longer
++			 * than any of these. */
++  			if (has_const_arg)
++			{
++				const_arg %= (GET_MODE_SIZE (mode) * 8);
++				if (const_arg == 0)
++				{
++					*total += COSTS_N_INSNS(1);
++					return true;
++				}
++
++				/* HImode shifts greater than 8 get optimized due
++				 * to register transfer from b to a; this cuts down the
++				 * cost. */
++				if (const_arg >= 8)
++				{
++					*total += COSTS_N_INSNS (1);
++					const_arg -= 8;
++				}
++
++				/* The computed cost is 'const_arg' 1-bit shifts, doubled
++				if in HImode, minus the cost of the constant itself which
++				will be added in later but really shouldn't be. */
++				*total += COSTS_N_INSNS (const_arg) * GET_MODE_SIZE (mode) - 1;
++				return true;
++			}
++			else
++			{
++				/* It may take up to 7 iterations of about 6-7 real
++				 * instructions, so make this expensive. */
++				*total += COSTS_N_INSNS (50);
++			}
++  			break;
++
++		case MULT:
++ 		{
++ 			/* Multiply is cheap when both arguments are 8-bits.  They
++ 			could be QImode, or QImode widened to HImode, or a constant
++ 			that fits into 8-bits.  As long as both operands qualify,
++ 			we can use a single mul instruction.
++  
++ 			Assume that fast multiply can be used, and change this if we find
++ 			differently... */
++ 			int ok_for_qihi3 = 1;
++  
++ 			/* Check the first operand */	
++ 			switch (GET_MODE (op0))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++ 					if (GET_CODE (op0) != SIGN_EXTEND && GET_CODE (op0) != ZERO_EXTEND)
++  						ok_for_qihi3 = 0;
++ 					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++  			}
++ 
++			/* Likewise, check the second operand.  This is where constants may appear. */
++ 			switch (GET_MODE (op1))
++ 			{
++ 				case QImode:
++ 					break;
++ 				case HImode:
++					if (GET_CODE (op1) != SIGN_EXTEND && GET_CODE (op1) != ZERO_EXTEND)
++ 						ok_for_qihi3 = 0;
++ 					break;
++ 				case VOIDmode:
++					if (!CONST_OK_FOR_LETTER_P (const_arg, 'K'))
++ 						ok_for_qihi3 = 0;
++					break;
++ 				default:
++ 					ok_for_qihi3 = 0;
++ 					break;
++ 			}
++ 
++ 			/* Fast multiply takes about 4 times as many cycles as a normal
++ 			arithmetic operation.  Otherwise, it will take an expensive libcall. */
++ 			if (ok_for_qihi3)
++ 				*total += COSTS_N_INSNS (4);
++ 			else
++ 				*total = COSTS_N_INSNS (50);
++  	  		break;
++ 		}
++
++		case DIV: case UDIV: case MOD: case UMOD:
++			/* These all require more expensive libcalls. */
++			*total += COSTS_N_INSNS (100);
++  			break;
++
++		/* TODO : TRUNCATE, SIGN_EXTEND, and ZERO_EXTEND */
++
++		/* These can normally be done with autoincrement, etc., so
++		 * don't charge for them. */
++		case PRE_DEC:
++		case PRE_INC:
++		case POST_DEC:
++		case POST_INC:
++			break;
++
++		default:
++			break;
++	}
++
++	/* Always return false, and let the caller gather the costs
++	 * of the operands */
++	return false;
++}
++
++
++static tree
++m6809_handle_fntype_attribute (tree *node, tree name,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs)
++{
++	if (TREE_CODE (*node) != FUNCTION_TYPE)
++	{
++		warning (WARNING_OPT "'%s' only valid for functions", 
++			IDENTIFIER_POINTER (name));
++		*no_add_attrs = TRUE;
++	}
++
++	return NULL_TREE;
++}
++
++
++static tree
++m6809_handle_data_type_attribute (tree *node ATTRIBUTE_UNUSED,
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED)
++{
++	return NULL_TREE;
++}
++
++
++
++static tree
++m6809_handle_default_attribute (tree *node ATTRIBUTE_UNUSED, 
++	tree name ATTRIBUTE_UNUSED,
++	tree args ATTRIBUTE_UNUSED,
++	int flags ATTRIBUTE_UNUSED,
++	bool *no_add_attrs ATTRIBUTE_UNUSED )
++{
++	return NULL_TREE;
++}
++
++
++/* Table of valid machine attributes */
++const struct attribute_spec m6809_attribute_table[] = { /*
++{ name,        min, max, decl,  type, fntype, handler } */
++{ "interrupt", 0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "naked",     0,   0,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "far",       0,   1,   false, true,  true,  m6809_handle_fntype_attribute },
++{ "bank",      0,   1,   true,  false, false, m6809_handle_default_attribute },
++{ "boolean",   0,   0,   false, true,  false, m6809_handle_data_type_attribute },
++{ NULL,        0,   0,   false, true,  false, NULL },
++};
++
++
++/** Initialize builtin routines for the 6809. */
++void
++m6809_init_builtins (void)
++{
++	/* Create type trees for each function signature required.
++	 *
++	 * void_ftype_void = void f(void)
++	 * void_ftype_uchar = void f(unsigned char)
++	 * uchar_ftype_uchar2 = unsigned char f (unsigned char, unsigned char)
++	 */
++	tree void_ftype_void = 
++		build_function_type (void_type_node, void_list_node);
++
++	tree void_ftype_uchar =
++		build_function_type (void_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node));
++
++	tree uchar_ftype_uchar2 =
++		build_function_type (unsigned_char_type_node,
++			tree_cons (NULL_TREE, unsigned_char_type_node, 
++				tree_cons (NULL_TREE, unsigned_char_type_node, void_list_node)));
++
++	/* Register each builtin function. */
++	add_builtin_function ("__builtin_swi", void_ftype_void,
++		M6809_SWI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi2", void_ftype_void,
++		M6809_SWI2, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_swi3", void_ftype_void,
++		M6809_SWI3, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_cwai", void_ftype_uchar,
++		M6809_CWAI, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sync", void_ftype_void,
++		M6809_SYNC, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_nop", void_ftype_void,
++		M6809_NOP, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_blockage", void_ftype_void,
++		M6809_BLOCKAGE, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_decimal", uchar_ftype_uchar2,
++		M6809_ADD_DECIMAL, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_add_carry", uchar_ftype_uchar2,
++		M6809_ADD_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++
++	add_builtin_function ("__builtin_sub_carry", uchar_ftype_uchar2,
++		M6809_SUB_CARRY, BUILT_IN_MD, NULL, NULL_TREE);
++}
++
++
++/** Used by m6809_expand_builtin, given a tree ARGLIST which
++ * refers to the operands of a builtin call, return an rtx
++ * that represents the nth operand, as denoted by OPNUM, which
++ * is a zero-based integer.  MODE gives the expected mode
++ * of the operand.
++ *
++ * This rtx is suitable for use in the emitted RTL for the
++ * builtin instruction. */
++rtx
++m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum)
++{
++	tree arg;
++	rtx r;
++
++	arg = CALL_EXPR_ARG (arglist, opnum);
++
++	/* Convert the tree to RTL */
++	r = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
++	if (r == NULL_RTX)
++		return NULL_RTX;
++	return r;
++}
++
++
++/** Expand a builtin that was registered in init_builtins into
++ * RTL.  */
++rtx
++m6809_expand_builtin (tree exp, 
++	rtx target, 
++	rtx subtarget ATTRIBUTE_UNUSED,
++	enum machine_mode mode ATTRIBUTE_UNUSED,
++	int ignore ATTRIBUTE_UNUSED )
++{
++   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
++	tree arglist = exp;
++	unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
++	rtx r0, r1;
++
++	switch (fcode)
++	{
++		case M6809_SWI:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 1);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI2:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 2);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_SWI3:
++			r0 = gen_rtx_CONST_INT (VOIDmode, 3);
++			emit_insn (target = gen_m6809_swi (r0));
++			return target;
++
++		case M6809_CWAI:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			emit_insn (target = gen_m6809_cwai (r0));
++			return target;
++
++		case M6809_SYNC:
++			emit_insn (target = gen_m6809_sync ());
++			return target;
++
++		case M6809_ADD_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_SUB_CARRY:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_subqi3_carry (target, r0, r1));
++			return target;
++
++		case M6809_NOP:
++			emit_insn (target = gen_nop ());
++			return target;
++
++		case M6809_BLOCKAGE:
++			emit_insn (target = gen_blockage ());
++			return target;
++
++		case M6809_ADD_DECIMAL:
++			r0 = m6809_builtin_operand (arglist, QImode, 0);
++			r1 = m6809_builtin_operand (arglist, QImode, 1);
++			if (!target)
++				target = gen_reg_rtx (QImode);
++			emit_insn (gen_addqi3_decimal (target, r0, r1));
++			return target;
++
++		default:
++			warning (WARNING_OPT "unknown builtin expansion ignored");
++			return NULL_RTX;
++	}
++}
++
++
++
++/* Returns nonzero if 'x' represents a function that was declared
++ * as __noreturn__. */
++int
++noreturn_functionp (rtx x)
++{
++	tree decl = call_target_decl (x);
++
++	if (decl == NULL_TREE)
++		return 0;
++	else
++		return TREE_THIS_VOLATILE (decl);
++}
++
++
++const char *
++far_function_type_p (tree type)
++{
++	tree attr;
++	const char *page;
++
++	/* Return whether or not this decl has the far attribute */
++	attr = lookup_attribute ("far", TYPE_ATTRIBUTES (type));
++	if (attr == NULL_TREE)
++		return NULL;
++
++	/* If it is far, check for a value */
++	attr = TREE_VALUE (attr);
++	if (attr == NULL_TREE)
++	{
++		warning (WARNING_OPT "far code page not specified, using local value");
++		return far_code_page;
++	}
++
++	/* We have a TREE_LIST of attribute values, get the first one.
++	 * It should be an INTEGER_CST. */
++	attr = TREE_VALUE (attr);
++	page = TREE_STRING_POINTER (attr);
++	return page;
++}
++
++
++/* For a far function, returns the identifier that states which page
++ * it resides in.  Otherwise, returns NULL for ordinary functions. */
++const char *
++far_functionp (rtx x)
++{
++	tree decl, decl_type;
++	const char *page;
++
++	/* Find the FUNCTION_DECL corresponding to the rtx being called. */
++	decl = call_target_decl (x);
++	if (decl == NULL_TREE)
++		return NULL;
++
++	/* See if the function has the new 'banked' attribute.  These
++	 * are numeric instead of text */
++	page = m6809_get_decl_bank (decl);
++	if (page)
++		return page;
++
++	/* No, lookup the type of the function and see if the type
++	 * specifies far or not. */
++	decl_type = TREE_TYPE (decl);
++	if (decl_type == NULL_TREE)
++		return NULL;
++	return far_function_type_p (decl_type);
++}
++
++
++
++/** Outputs the assembly language for a far call. */
++void
++output_far_call_insn (rtx *operands, int has_return)
++{
++	static char page_data[64];
++	const char *called_page;
++
++  /* The logic is the same for functions whether or not there
++	* is a return value.  Skip over the return value in this
++	* case, so that the call location is always operands[0].  */
++  if (has_return)
++	  operands++;
++
++  /* Get the name of the page being called */
++  called_page = far_functionp (operands[0]);
++
++#if 0 /* TODO : broken logic */
++  /* See if the called page name is a 'bank' */
++  if (isdigit (*called_page))
++  {
++    /* New style banking */
++	 if (!strcmp (called_page, current_bank_name))
++	 {
++	 	/* Same page */
++  	  	output_asm_insn ("jsr\t%0", operands);
++	 }
++	 else
++	 {
++	 	/* Different page */
++		output_asm_insn ("jsr\t__far_call_handler\t;new style", operands);
++  	  	output_asm_insn ("\t.dw\t%0", operands);
++		sprintf (page_data, "\t.db\t%s", called_page);
++	 	output_asm_insn (page_data, operands);
++	 }
++	 return;
++  }
++#endif
++
++  /* Are we calling a different page than we are running in? */
++  if (!strcmp (called_page, far_code_page))
++  {
++    /* Same page : no need to execute a far call */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t%C0", operands);
++		else
++			output_asm_insn ("jsr\t%0", operands);
++  }
++  else
++  {
++    /* Different page : need to emit far call thunk */
++
++    /* First output a call to the thunk for making far calls. */
++		if (flag_pic)
++			output_asm_insn ("lbsr\t__far_call_handler", operands);
++		else
++			output_asm_insn ("jsr\t__far_call_handler\t;old style", operands);
++  
++    /* Now output the name of the call site */
++    output_asm_insn ("\t.dw\t%C0", operands);
++  
++    /* Finally output the page number */
++    sprintf (page_data, "\t.db\t%s", far_functionp (operands[0]));
++    output_asm_insn (page_data, operands);
++  }
++}
++
++
++int
++m6809_init_cumulative_args (CUMULATIVE_ARGS cum ATTRIBUTE_UNUSED,
++     tree fntype,
++     rtx libname ATTRIBUTE_UNUSED)
++{
++	cum = 0;
++
++	/* For far functions, the current implementation does not allow for
++	 * stack parameters.  So note whenever the called function is far
++	 * and in a different page than the current one; such a function
++	 * should give an error if a stack parameter is generated. */
++	if (fntype)
++	{
++		const char *called_page = far_function_type_p (fntype);
++		if (called_page && strcmp (called_page, far_code_page) && !TARGET_FAR_STACK_PARAM)
++			cum |= CUM_STACK_INVALID;
++	}
++
++	if (fntype && TYPE_ARG_TYPES (fntype) != 0 &&
++		(TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype))) != void_type_node))
++	{
++		/* has variable arguments, cannot use registers */
++		cum |= (CUM_X_MASK | CUM_B_MASK | CUM_STACK_ONLY);
++	}
++
++	if (m6809_abi_version == M6809_ABI_VERSION_STACK)
++	{
++		/* cannot use registers ; only use the stack */
++		cum |= (CUM_STACK_ONLY | CUM_X_MASK | CUM_B_MASK);
++	}
++
++	return cum;
++}
++
++
++rtx
++m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump)
++{
++	if (*cump & CUM_STACK_INVALID)
++	{
++		*cump &= ~CUM_STACK_INVALID;
++		error ("far function needs stack, will not work");
++	}
++	return NULL_RTX;
++}
++
++void m6809_asm_trampoline_template(FILE *f)
++{
++	fprintf(f, "ldy #0000\n");
++	fprintf(f, "jmp 0x0000\n");
++}
++
++/*
++ * Trampoline output:
++ *
++ * ldu #&cxt      4 bytes   --LDY- ?? ??
++ * jmp fnaddr     3 bytes   JMP ?? ??
++ */
++void
++m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
++{
++	rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
++	/* TODO - optimize by generating the entire trampoline code here,
++	 * and removing the template altogether, since there are only two
++	 * bytes there that matter. */
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 2)), cxt);
++	emit_move_insn (gen_rtx_MEM (HImode, plus_constant (tramp, 5)), fnaddr);
++}
++
++
++/** Echo the version of the compiler and the name of the source file
++ * at the beginning of each assembler output file.  asm_out_file
++ * is a global FILE * pointing to the output stream. */
++void
++m6809_asm_file_start (void)
++{
++	const char *module_name;
++
++	fprintf (asm_out_file, "\n;;; gcc for m6809 : %s %s\n",
++		__DATE__, __TIME__);
++	fprintf (asm_out_file, ";;; %s\n", version_string);
++
++	fprintf (asm_out_file, ";;; ABI version %d\n", m6809_abi_version);
++	fprintf (asm_out_file, ";;; %s\n",
++		(TARGET_BYTE_INT ? "-mint8" : "-mint16"));
++	if (TARGET_EXPERIMENT)
++		fprintf (asm_out_file, ";;; -mexperiment\n");
++	if (TARGET_WPC)
++		fprintf (asm_out_file, ";;; -mwpc\n");
++	if (TARGET_6309)
++		fprintf (asm_out_file, ";;; -m6309\n");
++
++	/* Print the name of the module, which is taken as the base name
++	 * of the input file.
++	 * See the 'User-Defined Symbols' section of the assembler
++	 * documentation for the rules on valid symbols.
++	 */
++	module_name = lbasename (main_input_filename);
++
++	fprintf (asm_out_file, "\t.module\t");
++
++	if (*module_name >= '0' && *module_name <= '9')
++		fprintf (asm_out_file, "_");
++
++	while (*module_name)
++	{
++		if ((*module_name >= '0' && *module_name <= '9')
++			|| (*module_name >= 'A' && *module_name <= 'Z')
++			|| (*module_name >= 'a' && *module_name <= 'z')
++			|| *module_name == '$'
++			|| *module_name == '.'
++			|| *module_name == '_')
++		{
++			fprintf (asm_out_file, "%c", *module_name);
++		}
++		else
++		{
++			fprintf (asm_out_file, "_");
++		}
++		module_name++;
++	}
++
++	fprintf (asm_out_file, "\n");
++}
++
++
++/** Returns true if prologue/epilogue code is required for the
++ * current function being compiled.
++ *
++ * This is just the inverse of whether the function is declared as
++ * 'naked'.
++ */
++int
++prologue_epilogue_required (void)
++{
++	return !m6809_current_function_has_type_attr_p ("naked")
++		&& !m6809_current_function_has_type_attr_p ("noreturn");
++}
++
++
++/** Expand RTL for function entry */
++void
++emit_prologue_insns (void)
++{
++  rtx insn;
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  /* Save all registers used, including the frame pointer */
++  if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++  {
++    insn = emit_insn (
++      gen_rtx_register_pushpop (UNSPEC_PUSH_RS, live_regs));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Allocate space for local variables */
++  if (frame_size != 0)
++  {
++    insn = emit_insn (gen_rtx_stack_adjust (MINUS, frame_size));
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++
++  /* Set the frame pointer if it is needed */
++  if (frame_pointer_needed)
++  {
++    insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx);
++    RTX_FRAME_RELATED_P (insn) = 1;
++  }
++}
++
++
++/** Expand RTL for function exit */
++void
++emit_epilogue_insns (bool sibcall_p)
++{
++  unsigned int live_regs = m6809_get_live_regs ();
++  unsigned int frame_size = get_frame_size ();
++
++  if (frame_size != 0)
++    emit_insn (gen_rtx_stack_adjust (PLUS, frame_size));
++
++  if (sibcall_p)
++  {
++    if (live_regs)
++      emit_insn (gen_rtx_register_pushpop (UNSPEC_POP_RS, live_regs));
++  }
++  else
++  {
++    if (live_regs && !m6809_current_function_has_type_attr_p ("interrupt"))
++        emit_insn (
++          gen_rtx_register_pushpop (UNSPEC_POP_RS, PC_REGBIT | live_regs));
++  
++    if (m6809_current_function_has_type_attr_p ("interrupt"))
++      emit_jump_insn (gen_return_rti ());
++    else
++      emit_jump_insn (gen_return_rts ());
++  }
++}
++
++#if 0
++/** Predefine some preprocessor names according to the currently
++ * selected compiler options */
++void
++m6809_cpu_cpp_builtins (void)
++{
++	if (TARGET_6309)
++	{
++		builtin_define_std ("__M6309__");
++		builtin_define_std ("__m6309__");
++	}
++	else
++	{
++		builtin_define_std ("__M6809__");
++		builtin_define_std ("__m6809__");
++	}
++
++	if (TARGET_BYTE_INT)
++		builtin_define_std ("__int8__");
++	else
++		builtin_define_std ("__int16__");
++
++	switch (m6809_abi_version)
++	{
++		case M6809_ABI_VERSION_STACK:
++			builtin_define_std ("__regargs__");
++			builtin_define_std ("__ABI_STACK__");
++			break;
++		case M6809_ABI_VERSION_REGS:
++			builtin_define_std ("__ABI_REGS__");
++			break;
++		case M6809_ABI_VERSION_BX:
++			builtin_define_std ("__ABI_BX__");
++			break;
++		default:
++			break;
++	}
++
++	if (TARGET_WPC)
++		builtin_define_std ("__WPC__");
++
++	if (TARGET_DRET)
++		builtin_define_std ("__DRET__");
++}
++#endif
++
++#define MAX_ASM_ASCII_STRING 48
++
++void
++m6809_output_ascii (FILE *fp, const char *str, unsigned long size)
++{
++	unsigned long i;
++	bool use_ascii = true;
++
++	/* If the size is too large, then break this up into multiple
++	outputs.  The assembler can only output roughly 48 bytes at a
++	time.  Note that if there are lots of escape sequences in
++	the string, this may fail. */
++	if (size > MAX_ASM_ASCII_STRING)
++	{
++		m6809_output_ascii (fp, str, MAX_ASM_ASCII_STRING);
++		m6809_output_ascii (fp, str + MAX_ASM_ASCII_STRING, 
++			size - MAX_ASM_ASCII_STRING);
++		return;
++	}
++
++	/* Check for 8-bit codes, which cannot be embedded in an .ascii */
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++		if (c >= 0x80)
++		{
++			use_ascii = false;
++			break;
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\t.ascii \"");
++
++	for (i = 0; i < size; i++)
++	{
++		int c = str[i] & 0377;
++
++		if (use_ascii)
++		{
++		/* Just output the plain character if it is printable,
++		otherwise output the escape code for the character.
++		The assembler recognizes the same C-style octal escape sequences,
++		except that it only supports 7-bit codes. */
++		if (c >= ' ' && c < 0177 && c != '\\' && c != '"')
++  			putc (c, fp);
++		else switch (c) 
++		{
++			case '\n':
++#ifndef TARGET_COCO
++				fputs ("\\n", fp);
++				break;
++#endif
++				/* On the CoCo, we fallthrough and treat '\n' like '\r'. */
++			case '\r':
++				fputs ("\\r", fp);
++				break;
++			case '\t':
++				fputs ("\\t", fp);
++				break;
++			case '\f':
++				fputs ("\\f", fp);
++				break;
++			case 0:
++				fputs ("\\0", fp);
++				break;
++			default:
++				fprintf (fp, "\\%03o", c);
++				break;
++		}
++		}
++		else
++		{
++			fprintf (fp, "\t.byte\t0x%02X\n", c);
++		}
++	}
++
++	if (use_ascii)
++		fprintf (fp, "\"\n");
++}
++
++
++void
++m6809_output_quoted_string (FILE *asm_file, const char *string)
++{
++	char c;
++
++	if (strlen (string) > MAX_ASM_ASCII_STRING)
++	{
++		/* The string length is too large.  We'll have to truncate it.
++		This is only called from debugging functions, so it's usually
++		not critical. */
++
++		char truncated_string[MAX_ASM_ASCII_STRING+1];
++
++		/* Copy as many characters as we can. */
++		strncpy (truncated_string, string, MAX_ASM_ASCII_STRING);
++		truncated_string[MAX_ASM_ASCII_STRING] = '\0';
++		string = truncated_string;
++	}
++
++	/* Copied from toplev.c */
++
++	putc ('\"', asm_file);
++	while ((c = *string++) != 0) {
++		if (ISPRINT (c)) {
++			if (c == '\"' || c == '\\')
++				putc ('\\', asm_file);
++			putc (c, asm_file);
++		}
++      else
++			fprintf (asm_file, "\\%03o", (unsigned char) c);
++	}
++	putc ('\"', asm_file);
++}
++
++
++/** Output the assembly code for a shift instruction where the
++ * shift count is not constant. */
++void
++m6809_output_shift_insn (int rtx_code, rtx *operands)
++{
++	struct shift_opcode *op;
++
++	if (GET_CODE (operands[2]) == CONST_INT)
++		abort ();
++
++	if (optimize_size && GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("jsr\t_ashlhi3", operands);
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("jsr\t_ashrhi3", operands);
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("jsr\t_lshrhi3", operands);
++				break;
++		}
++	}
++	else if (GET_MODE (operands[0]) == HImode)
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", "rola");
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asra", "rorb");
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsra", "rorb");
++				break;
++		}
++	}
++	else
++	{
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				m6809_gen_register_shift (operands, "aslb", NULL);
++				break;
++			case ASHIFTRT:
++				m6809_gen_register_shift (operands, "asrb", NULL);
++				break;
++			case LSHIFTRT:
++				m6809_gen_register_shift (operands, "lsrb", NULL);
++				break;
++		}
++	}
++}
++
++
++void
++m6809_emit_move_insn (rtx dst, rtx src)
++{
++	emit_insn (gen_rtx_SET (VOIDmode, dst, src));
++	if (ACC_A_REG_P (dst))
++		emit_insn (gen_rtx_USE (VOIDmode, dst));
++}
++
++
++/** Split a complex shift instruction into multiple CPU
++ * shift instructions. */
++void
++m6809_split_shift (enum rtx_code code, rtx *operands)
++{
++	enum machine_mode mode;
++	int count;
++
++	mode = GET_MODE (operands[0]);
++	count = INTVAL (operands[2]);
++	
++	/* Handle a shift count outside the range of 0 .. N-1, where
++	 * N is the mode size in bits.  We normalize the count, and
++	 * for negative counts we also invert the direction of the
++	 * shift. */
++	if ((count < 0) || (count >= 8 * GET_MODE_SIZE (mode)))
++	{
++		if (count < 0)
++		{
++			count = -count;
++			code = (code == ASHIFT) ? ASHIFTRT : ASHIFT;
++		}
++		count %= (8 * GET_MODE_SIZE (mode));
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, count)));
++	}
++
++	/* Handle shift by zero explicitly as a no-op. */
++	if (count == 0)
++	{
++		emit_insn (gen_nop ());
++		return;
++	}
++
++	/* Decompose the shift by a constant N > 8 into two
++	 * shifts, first by 8 and then by N-8.
++	 * This "speeds up" the process for large shifts that would be
++	 * handled below, but allows for some optimization.
++	 * In some cases shift by 8 can be implemented fast.  If an
++	 * instruction to shift by 8 is defined, it will be used here;
++	 * otherwise it will be further decomposed as below. */
++	if (mode == HImode && count > 8)
++	{
++		rtx output = operands[0];
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, 8)));
++
++		/* Unsigned shifts always produce a zero in either the
++		 * upper or lower half of the output; then, that part
++		 * does not need to be shifted anymore.  We modify the
++		 * output and the subsequent instructions to operate in
++		 * QImode only on the relevant part. */
++		if (REG_P (output))
++		{
++			if (code == ASHIFT)
++			{
++				output = gen_rtx_REG (QImode, HARD_A_REGNUM);
++				mode = QImode;
++			}
++			else
++			{
++				output = gen_rtx_REG (QImode, HARD_D_REGNUM);
++				mode = QImode;
++			}
++		}
++
++		m6809_emit_move_insn (output,
++			gen_rtx_fmt_ee (code, mode, copy_rtx (output), 
++				gen_rtx_CONST_INT (VOIDmode, count-8)));
++		return;
++	}
++
++	/* Rewrite the unsigned shift of an 8-bit register by a large constant N
++	 * (near to the maximum of 8) as a rotate and mask. */
++	if (mode == QImode && REG_P (operands[0]) && count >= ((code == ASHIFTRT) ? 7 : 6))
++	{
++		unsigned int mask;
++		unsigned int was_signed = (code == ASHIFTRT);
++
++		code = (code == ASHIFT) ? ROTATERT : ROTATE;
++		if (code == ROTATE)
++			mask = (count == 6) ? 0x03 : 0x01;
++		else
++			mask = (count == 6) ? 0xC0 - 0x100 : 0x80 - 0x100;
++		count = 9 - count;
++
++		do {
++			m6809_emit_move_insn (operands[0],
++				gen_rtx_fmt_ee (code, QImode, operands[1], const1_rtx));
++		} while (--count != 0);
++
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (AND, QImode, operands[1],
++				gen_rtx_CONST_INT (VOIDmode, mask)));
++
++		if (was_signed)
++		{
++			emit_insn (gen_negqi2 (operands[0], copy_rtx (operands[0])));
++			if (ACC_A_REG_P (operands[0]))
++				emit_insn (gen_rtx_USE (VOIDmode, operands[0]));
++		}
++		return;
++	}
++
++	/* Decompose the shift by any constant N > 1 into a sequence
++	 * of N shifts.
++	 * This is done recursively, by creating a shift by 1 and a
++	 * shift by N-1, as long as N>1. */
++	if (count > 1)
++	{
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], const1_rtx));
++	
++		m6809_emit_move_insn (operands[0],
++			gen_rtx_fmt_ee (code, mode, operands[1], 
++				gen_rtx_CONST_INT (VOIDmode, count-1)));
++		return;
++	}
++	
++	/* Decompose the single shift of a 16-bit quantity into two
++	 * CPU instructions, one for each 8-bit half.
++	 */
++	if (mode == HImode && count == 1)
++	{
++		rtx first, second;
++		enum rtx_code rotate_code;
++
++		rotate_code = (code == ASHIFT) ? ROTATE : ROTATERT;
++
++		/* Split the operand into two 8-bit entities.
++		 * FIRST is the one that will get shifted via a regular CPU
++		 * instruction.
++		 * SECOND is the one that will have the result of the first shift
++		 * rotated in.
++		 *
++		 * We initialize first and second as if we are doing a left shift,
++		 * then swap the operands if it's a right shift.
++		 */
++		if (REG_P (operands[0]))
++		{
++			first = gen_rtx_REG (QImode, HARD_D_REGNUM); /* HARD_B_REGNUM? */
++			second = gen_rtx_REG (QImode, HARD_A_REGNUM);
++		}
++		else
++		{
++			first = adjust_address (operands[0], QImode, 1);
++			second = adjust_address (operands[0], QImode, 0);
++		}
++
++		if (rotate_code == ROTATERT)
++		{
++			rtx tmp; tmp = first; first = second; second = tmp;
++		}
++
++		/* Decompose into a shift and a rotate instruction. */
++		m6809_emit_move_insn (first,
++			gen_rtx_fmt_ee (code, QImode, copy_rtx (first), const1_rtx));
++		m6809_emit_move_insn (second,
++			gen_rtx_fmt_ee (rotate_code, QImode, copy_rtx (second), const1_rtx));
++		return;
++	}
++}
++
++
++/** Adjust register usage based on compile-time flags. */
++void
++m6809_conditional_register_usage (void)
++{
++	unsigned int soft_regno;
++
++#ifdef CONFIG_SOFT_REGS_ALWAYS
++	m6809_soft_regs = CONFIG_SOFT_REGS_ALWAYS;
++#else
++	if (!m6809_soft_reg_count)
++		return;
++	m6809_soft_regs = atoi (m6809_soft_reg_count);
++#endif
++
++	if (m6809_soft_regs == 0)
++		return;
++
++	if (m6809_soft_regs > NUM_M_REGS)
++		m6809_soft_regs = NUM_M_REGS;
++
++	/* Registers are marked FIXED by default.  Free up if
++	the user wishes. */
++	for (soft_regno = 1; soft_regno < m6809_soft_regs; soft_regno++)
++	{
++		fixed_regs[SOFT_M0_REGNUM + soft_regno] = 0;
++
++		/* Mark the softregs as call-clobbered, so that they need
++		 * not be saved/restored on function entry/exit. */
++		call_used_regs[SOFT_M0_REGNUM + soft_regno] = 1;
++	}
++}
++
++
++/** Return a RTX representing how to return a value from a function.
++  VALTYPE gives the type of the value, FUNC identifies the function
++  itself.
++
++  In general, we only care about the width of the result. */
++rtx
++m6809_function_value (const tree valtype, const tree func ATTRIBUTE_UNUSED)
++{
++   unsigned int regno;
++	enum machine_mode mode;
++
++	/* Get the mode (i.e. width) of the result. */
++	mode = TYPE_MODE (valtype);
++
++	if (lookup_attribute ("boolean", TYPE_ATTRIBUTES (valtype)))
++      regno = HARD_Z_REGNUM;
++   else if (mode == QImode || (TARGET_DRET && mode == HImode))
++      regno = HARD_D_REGNUM;
++   else
++      regno = HARD_X_REGNUM;
++   return gen_rtx_REG (mode, regno);
++}
++
++
++/** Return 1 if REGNO is possibly needed to return the result
++of a function, 0 otherwise. */
++int
++m6809_function_value_regno_p (unsigned int regno)
++{
++	if (regno == HARD_Z_REGNUM)
++		return 1;
++	else if ((TARGET_BYTE_INT || TARGET_DRET) && regno == HARD_D_REGNUM)
++		return 1;
++	else if (!TARGET_DRET && regno == HARD_X_REGNUM)
++		return 1;
++	else
++		return 0;
++}
++
++
++#ifdef TRACE_PEEPHOLE
++int
++m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage)
++{
++	if (stage == PEEP_END)
++	{
++		printf ("%s: peephole %d pattern and predicate matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	else if (stage == PEEP_COND)
++	{
++		printf ("%s: peephole %d? at least pattern matched\n",
++			main_input_filename, peephole_id);
++		fflush (stdout);
++	}
++	return 1;
++}
++#else
++int
++m6809_match_peephole2 (unsigned int peephole_id ATTRIBUTE_UNUSED,
++	unsigned int stage ATTRIBUTE_UNUSED)
++{
++	return 1;
++}
++#endif /* TRACE_PEEPHOLE */
++
++
++/** Return 1 if it is OK to store a value of MODE in REGNO. */
++int
++m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
++{
++   /* Soft registers, as they are just memory, can really hold
++   values of any type.  However we restrict them to values of
++   size HImode or QImode to prevent exhausting them for larger
++   values.
++      Word values cannot be placed into the first soft register,
++   as it is the low byte that is being placed there, which
++   corrupts the (non-soft) register before it. */
++   if (M_REGNO_P (regno))
++   {
++      switch (GET_MODE_SIZE (mode))
++      {
++         case 1:
++            return 1;
++         case 2:
++            return regno != SOFT_M0_REGNUM;
++         default:
++            return 0;
++      }
++   }
++
++   /* VOIDmode can be stored anywhere */
++   else if (mode == VOIDmode)
++      return 1;
++
++   /* Zero is a reserved register, but problems occur if we don't
++   say yes here??? */
++   else if (regno == 0)
++      return 1;
++
++   /* For other registers, return true only if the requested size
++   exactly matches the hardware size. */
++   else if ((G_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 2))
++      return 1;
++   else if ((BYTE_REGNO_P (regno)) && (GET_MODE_SIZE (mode) == 1))
++      return 1;
++   else
++      return 0;
++}
++
++
++/* exp is the call expression.  DECL is the called function,
++ * or NULL for an indirect call */
++bool
++m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
++{
++	tree type, arg;
++   const char *name;
++	bool result = 0;
++	int argcount = 0;
++	int step = 1;
++
++	/* If there is no DECL, it is an indirect call.
++	 * Never optimize this??? */
++	if (decl == NULL)
++		goto done;
++
++	/* Never allow an interrupt handler to be optimized this way. */
++	if (m6809_function_has_type_attr_p (decl, "interrupt"))
++		goto done;
++
++	/* Skip sibcall if the type can't be found for
++	 * some reason */
++	step++;
++	name = IDENTIFIER_POINTER (DECL_NAME (decl));
++	type = TREE_TYPE (decl);
++	if (type == NULL)
++		goto done;
++
++	/* Skip sibcall if the target is a far function */
++	step++;
++	if (far_function_type_p (type) != NULL)
++		goto done;
++
++	/* Skip sibcall if the called function's arguments are
++	 * variable */
++	step++;
++	if (TYPE_ARG_TYPES (type) == NULL)
++		goto done;
++
++	/* Allow sibcalls in other cases. */
++	result = 1;
++done:
++	/* printf ("%s ok for sibcall? %s, step %d, args %d\n", name, result ? "yes" : "no", step, argcount); */
++	return result;
++}
++
++
++/** Emit code for the 'casesi' pattern.
++ * This pattern is only used in 8-bit mode, and can be disabled
++ * with -mold-case there as well.  The rationale for this is to
++ * do a better job than the simpler but well-tested 'tablejump'
++ * method.
++ *
++ * For small jumptables, where the switch expression is an
++ * 8-bit value, the lookup can be done more efficiently
++ * using the "B,X" style index mode. */
++void
++m6809_do_casesi (rtx index, rtx lower_bound, rtx range,
++	rtx table_label, rtx default_label)
++{
++	enum machine_mode mode;
++	rtx scaled;
++	rtx table_in_reg;
++
++	/* expr.c has to be patched so that it does not promote
++	 * the expression to SImode, but rather to HImode.
++	 * Fail now if that isn't the case. */
++	if (GET_MODE_SIZE (GET_MODE (index)) > GET_MODE_SIZE (HImode))
++		error ("try_casesi promotion bug");
++
++	/* Determine whether or not we are going to work primarily in
++	 * QImode or HImode.  This depends on the size of the index
++	 * into the lookup table.  QImode can only be used when the
++	 * index is less than 0x40, since it will be doubled but
++	 * must remain unsigned. */
++	if ((GET_CODE (range) == CONST_INT) && (INTVAL (range) < 0x40))
++		mode = QImode;
++	else
++		mode = HImode;
++
++	/* Convert to QImode if necessary */
++	if (mode == QImode)
++	{
++		index = gen_lowpart_general (mode, index);
++		lower_bound = gen_lowpart_general (mode, lower_bound);
++	}
++
++	/* Translate from case value to table index by subtraction */
++	if (lower_bound != const0_rtx)
++		index = expand_binop (mode, sub_optab, index, lower_bound,
++			NULL_RTX, 0, OPTAB_LIB_WIDEN);
++
++	/* Emit compare-and-jump to test for index out-of-range */
++	emit_cmp_and_jump_insns (index, range, GTU, NULL_RTX, mode, 1,
++		default_label);
++
++	/* Put the table address is in a register */
++	table_in_reg = gen_reg_rtx (Pmode);
++	emit_move_insn (table_in_reg, gen_rtx_LABEL_REF (Pmode, table_label));
++
++	/* Emit table lookup and jump */
++	if (mode == QImode)
++	{
++		/* Scale the index */
++		scaled = gen_reg_rtx (QImode);
++		emit_insn (gen_ashlqi3 (scaled, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_short_offset (scaled, table_in_reg));
++	}
++	else
++	{
++		/* Scale the index */
++		emit_insn (gen_ashlhi3 (index, index, const1_rtx));
++
++		/* Emit the jump */
++		emit_jump_insn (gen_tablejump_long_offset (index, table_in_reg));
++	}
++
++	/* Copied from expr.c */
++	if (!CASE_VECTOR_PC_RELATIVE && !flag_pic)
++		emit_barrier ();
++}
++
++
++/** Output the assembly code for a 32-bit add/subtract. */
++void
++m6809_output_addsi3 (int rtx_code, rtx *operands)
++{
++	rtx xoperands[8];
++	rtx dst = operands[0];
++
++	/* Prepare the operands by splitting each SImode into two HImodes
++	that can be operated independently.  The high word of operand 1
++	is further divided into two QImode components for use with 'adc'
++	style instructions. */
++	xoperands[7] = operands[3];
++
++	xoperands[0] = adjust_address (dst, HImode, 2);
++	xoperands[3] = adjust_address (dst, HImode, 0);
++
++#if 1
++	xoperands[2] = adjust_address (operands[1], HImode, 2);
++	xoperands[6] = adjust_address (operands[1], HImode, 0);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[1] = gen_int_mode (INTVAL (operands[2]) & 0xFFFF, HImode);
++		xoperands[4] = gen_int_mode ((INTVAL (operands[2]) >> 24) & 0xFF, QImode);
++		xoperands[5] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFF, QImode);
++	}
++	else
++	{
++		xoperands[1] = adjust_address (operands[2], HImode, 2);
++		xoperands[4] = adjust_address (operands[2], QImode, 0);
++		xoperands[5] = adjust_address (operands[2], QImode, 1);
++	}
++
++#endif
++
++#if 0
++	xoperands[1] = adjust_address (operands[1], HImode, 2);
++	xoperands[4] = adjust_address (operands[1], QImode, 0);
++	xoperands[5] = adjust_address (operands[1], QImode, 1);
++
++	/* Operand 2 may be a MEM or a CONST_INT */
++	if (GET_CODE (operands[2]) == CONST_INT)
++	{
++		xoperands[2] = gen_int_mode ((INTVAL (operands[2])) & 0xFFFF, HImode);
++		xoperands[6] = gen_int_mode ((INTVAL (operands[2]) >> 16) & 0xFFFF, HImode);
++	}
++	else
++	{
++		xoperands[2] = adjust_address (operands[2], HImode, 2);
++		xoperands[6] = adjust_address (operands[2], HImode, 0);
++	}
++#endif
++
++	/* Output the assembly code. */
++	if (rtx_code == PLUS)
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("add%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("adcb\t%5", xoperands);
++		output_asm_insn ("adca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++	else
++	{
++		output_asm_insn ("ld%7\t%2", xoperands);
++		output_asm_insn ("sub%7\t%1", xoperands);
++		output_asm_insn ("st%7\t%0", xoperands);
++		output_asm_insn ("ld%7\t%6", xoperands);
++		output_asm_insn ("sbcb\t%5", xoperands);
++		output_asm_insn ("sbca\t%4", xoperands);
++		output_asm_insn ("st%7\t%3", xoperands);
++	}
++}
++
++
++#if 0
++/** Output the assembly code for a 32-bit shift.
++Operands 0 and 1 must be the same rtx, forced by a matching
++constraint.  Operand 2 must be a CONST_INT.  Operand 3 is
++"d" in case a temporary reg is needed. */
++void
++m6809_output_shiftsi3 (int rtx_code, rtx *operands)
++{
++	unsigned int count = INTVAL (operands[2]) % 32;
++	unsigned int size = 4; /* sizeof (SImode) */
++	int s;
++	rtx xoperands[4];
++	int op;
++	int start, end, step;
++
++	/* Initialize */
++	if (rtx_code == ASHIFT)
++	{
++		start = size-1;
++		end = -1;
++		step = -1;
++	}
++	else
++	{
++		start = 0;
++		end = size;
++		step = 1;
++	}
++
++	xoperands[2] = operands[2];
++	xoperands[3] = operands[3];
++
++	if (count <= 0)
++		abort ();
++	if (rtx_code == ROTATE || rtx_code == ROTATERT)
++		abort ();
++
++	/* Extract bit shifts over 16 bits by HImode moves. */
++	if (count >= 16)
++	{
++	}
++
++	/* Extract bit shifts over 8 bits by QImode moves. */
++	if (count >= 8)
++	{
++	}
++
++	/* Iterate over the number of bits to be shifted. */
++	while (count > 0)
++	{
++		/* Each bit to be shifted requires 1 proper bit shift
++		and 3 rotates. */
++
++		/* First, do the arithmetic/logical shift.  Left shifts
++		start from the LSB; right shifts start from the MSB. */
++		xoperands[0] = adjust_address (operands[0], QImode, start);
++		switch (rtx_code)
++		{
++			case ASHIFT:
++				output_asm_insn ("asl\t%0", xoperands);
++				start--;
++				break;
++			case ASHIFTRT:
++				output_asm_insn ("asr\t%0", xoperands);
++				start++;
++				break;
++			case LSHIFTRT:
++				output_asm_insn ("lsr\t%0", xoperands);
++				start++;
++				break;
++		}
++
++		/* Next, rotate the other bytes */
++		for (s = start; s != end; s += step)
++		{
++			xoperands[0] = adjust_address (operands[0], QImode, s);
++			switch (rtx_code)
++			{
++				case ASHIFT:
++					output_asm_insn ("rol\t%0", xoperands);
++					break;
++				case ASHIFTRT:
++				case LSHIFTRT:
++					output_asm_insn ("ror\t%0", xoperands);
++					break;
++			}
++		}
++		count--;
++	}
++}
++#endif
++
++int
++power_of_two_p (unsigned int n)
++{
++	return (n & (n-1)) == 0;
++}
++
++
++int
++m6809_can_eliminate (int from, int to)
++{
++	if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
++		return !frame_pointer_needed;
++	return 1;
++}
++
++
++int
++m6809_initial_elimination_offset (int from, int to)
++{
++	switch (from)
++	{
++		case ARG_POINTER_REGNUM:
++			return get_frame_size () + m6809_get_regs_size (m6809_get_live_regs ());
++		case FRAME_POINTER_REGNUM:
++			return get_frame_size ();
++		default:
++			gcc_unreachable ();
++	}
++}
++
++
++bool
++m6809_frame_pointer_required (void)
++{
++	return false;
++}
++
++
++/* Defines the target-specific hooks structure. */
++struct gcc_target targetm = TARGET_INITIALIZER;
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.h gcc-4.6.4/gcc/config/m6809/m6809.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.h	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,1336 @@
++/* Definitions of target machine for GNU compiler.  MC6809 version.
++
++ MC6809 Version by Tom Jones (jones@sal.wisc.edu)
++ Space Astronomy Laboratory
++ University of Wisconsin at Madison
++
++ minor changes to adapt it to gcc-2.5.8 by Matthias Doerfel
++ ( msdoerfe@informatik.uni-erlangen.de )
++ also added #pragma interrupt (inspired by gcc-6811)
++
++ minor changes to adapt it to gcc-2.8.0 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to egcs-1.1.2 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ minor changes to adapt it to gcc-2.95.3 by Eric Botcazou
++ (ebotcazou@multimania.com)
++
++ changes for gcc-3.1.1 by ???
++
++ further changes for gcc-3.1.1 and beyond by Brian Dominy
++ (brian@oddchange.com)
++
++ even more changes for gcc-4.6.1 by William Astle (lost@l-w.ca)
++
++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/>.  */
++
++
++/* Helper macros for creating strings with macros */
++#define C_STRING(x) C_STR(x)
++#define C_STR(x) #x
++
++/* Certain parts of GCC include host-side includes, which is bad.
++ * Some things that get pulled in need to be undone.
++ */
++#undef HAVE_GAS_HIDDEN
++
++/* Names to predefine in the preprocessor for this target machine.  */
++/*#define TARGET_CPU_CPP_BUILTINS() m6809_cpu_cpp_builtins () */
++#define TARGET_CPU_CPP_BUILTINS() do \
++	{ \
++		if (TARGET_6309) \
++		{ \
++			builtin_define_std ("__M6309__"); \
++			builtin_define_std ("__m6309__"); \
++		} \
++		else \
++		{ \
++			builtin_define_std ("__M6809__"); \
++			builtin_define_std ("__m6809__"); \
++		} \
++ \
++		if (TARGET_BYTE_INT) \
++			builtin_define_std ("__int8__"); \
++		else \
++			builtin_define_std ("__int16__"); \
++ \
++		switch (m6809_abi_version) \
++		{ \
++			case M6809_ABI_VERSION_STACK: \
++				builtin_define_std ("__regargs__"); \
++				builtin_define_std ("__ABI_STACK__"); \
++				break; \
++			case M6809_ABI_VERSION_REGS: \
++				builtin_define_std ("__ABI_REGS__"); \
++				break; \
++			case M6809_ABI_VERSION_BX: \
++				builtin_define_std ("__ABI_BX__"); \
++				break; \
++			default: \
++				break; \
++		} \
++ \
++		if (TARGET_WPC) \
++			builtin_define_std ("__WPC__"); \
++ \
++		if (TARGET_DRET) \
++			builtin_define_std ("__DRET__"); \
++	} while (0)
++
++/* As an embedded target, we have no libc.  */
++#ifndef inhibit_libc
++#define inhibit_libc
++#endif
++
++/* Print subsidiary information on the compiler version in use.  */
++#define TARGET_VERSION fprintf (stderr, " (MC6809)");
++
++/* Run-time compilation parameters selecting different hardware subsets.  */
++/*extern int target_flags; */
++extern short *reg_renumber;	/* def in local_alloc.c */
++
++/* Runtime current values of section names */
++extern int section_changed;
++extern char code_section_op[], data_section_op[], bss_section_op[];
++
++#define WARNING_OPT 0,
++/*extern const char *m6809_abi_version_ptr; */
++extern unsigned int m6809_soft_regs;
++extern unsigned int m6809_abi_version;
++
++/* ABI versions */
++
++#define M6809_ABI_VERSION_STACK 0
++#define M6809_ABI_VERSION_REGS 1
++#define M6809_ABI_VERSION_BX 2
++#define M6809_ABI_VERSION_LATEST  (M6809_ABI_VERSION_BX)
++
++/* Allow $ in identifiers */
++#define DOLLARS_IN_IDENTIFIERS 1
++
++/*--------------------------------------------------------------
++	Target machine storage layout
++--------------------------------------------------------------*/
++
++/* Define this if most significant bit is lowest numbered
++   in instructions that operate on numbered bit-fields.  */
++#define BITS_BIG_ENDIAN 0
++
++/* Define to 1 if most significant byte of a word is the lowest numbered. */
++#define BYTES_BIG_ENDIAN 1
++
++/* Define to 1 if most significant word of a multiword value is the lowest numbered. */
++#define WORDS_BIG_ENDIAN 1
++
++/* Number of bits in an addressible storage unit */
++#define BITS_PER_UNIT 8
++
++/* Width in bits of a "word", or the contents of a machine register.
++ * Although the 6809 has a few byte registers, define this to 16-bits
++ * since this is the natural size of most registers. */
++#define BITS_PER_WORD 16
++
++/* Width of a word, in units (bytes).  */
++#define UNITS_PER_WORD (BITS_PER_WORD/8)
++
++/* Width in bits of a pointer.  See also the macro `Pmode' defined below.  */
++#define POINTER_SIZE 16
++
++/* Allocation boundary (bits) for storing pointers in memory.  */
++#define POINTER_BOUNDARY 8
++
++/* Allocation boundary (bits) for storing arguments in argument list.  */
++/* PARM_BOUNDARY is divided by BITS_PER_WORD in expr.c -- tej */
++#define PARM_BOUNDARY 8
++
++/* Boundary (bits) on which stack pointer should be aligned.  */
++#define STACK_BOUNDARY 8
++
++/* Allocation boundary (bits) for the code of a function.  */
++#define FUNCTION_BOUNDARY 8
++
++/* Alignment of field after `int : 0' in a structure.  */
++#define EMPTY_FIELD_BOUNDARY 8
++
++/* Every structure's size must be a multiple of this.  */
++#define STRUCTURE_SIZE_BOUNDARY 8
++
++/* Largest mode size to use when putting an object, including
++ * a structure, into a register.  By limiting this to 16, no
++ * 32-bit objects will ever be allocated to a pair of hard
++ * registers.  This is a good thing, since there aren't that
++ * many of them.  32-bit objects are only needed for floats
++ * and "long long"s.  Larger values have been tried and did not
++ * work. */
++#define MAX_FIXED_MODE_SIZE 16
++
++/* No data type wants to be aligned rounder than this.  */
++#define BIGGEST_ALIGNMENT 8
++
++/* Define this if move instructions will actually fail to work
++   when given unaligned data.  */
++#define STRICT_ALIGNMENT 0
++
++/*--------------------------------------------------------------
++	 Standard register usage.
++--------------------------------------------------------------*/
++
++/* Register values as bitmasks.
++ * TODO : merge D_REGBIT and B_REGBIT, and treat this as the same
++ * register. */
++#define RSVD1_REGBIT    (1 << HARD_RSVD1_REGNUM)
++#define D_REGBIT			(1 << HARD_D_REGNUM)
++#define X_REGBIT			(1 << HARD_X_REGNUM)
++#define Y_REGBIT			(1 << HARD_Y_REGNUM)
++#define U_REGBIT			(1 << HARD_U_REGNUM)
++#define S_REGBIT			(1 << HARD_S_REGNUM)
++#define PC_REGBIT			(1 << HARD_PC_REGNUM)
++#define Z_REGBIT        (1 << HARD_Z_REGNUM)
++#define A_REGBIT			(1 << HARD_A_REGNUM)
++#define B_REGBIT			(1 << HARD_B_REGNUM)
++#define CC_REGBIT			(1 << HARD_CC_REGNUM)
++#define DP_REGBIT			(1 << HARD_DP_REGNUM)
++#define SOFT_FP_REGBIT  (1 << SOFT_FP_REGNUM)
++#define SOFT_AP_REGBIT  (1 << SOFT_AP_REGNUM)
++#define M_REGBIT(n)		(1 << (SOFT_M0_REGNUM + n))
++
++/* Macros for dealing with set of registers.
++ * A register set is just a bitwise-OR of all the register
++ * bitmask values. */
++
++/* Which registers can hold 8-bits */
++#define BYTE_REGSET \
++	(Z_REGBIT | A_REGBIT | D_REGBIT | CC_REGBIT | DP_REGBIT)
++
++/* Which registers can hold 16-bits.
++ * Note: D_REGBIT is defined as both an 8-bit and 16-bit register */
++#define WORD_REGSET \
++	(D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT | SOFT_FP_REGBIT | SOFT_AP_REGBIT | RSVD1_REGBIT)
++
++/* Returns nonzero if a given REGNO is in the REGSET. */
++#define REGSET_CONTAINS_P(regno, regset)  (((1 << (regno)) & (regset)) != 0)
++
++/* Defines related to the number of soft registers supported.
++ * The actual number used may be less depending on -msoft-reg-count.
++ * If you change one of these, you should change them all. */
++#define NUM_M_REGS 8
++#define M_REGS_FIXED 1, 1, 1, 1, 1, 1, 1, 1
++#define M_REGS_CALL_USED 1, 1, 1, 1, 1, 1, 1, 1
++#define HARD_M_REGNUMS \
++   SOFT_M0_REGNUM+0, SOFT_M0_REGNUM+1, SOFT_M0_REGNUM+2, SOFT_M0_REGNUM+3, \
++   SOFT_M0_REGNUM+4, SOFT_M0_REGNUM+5, SOFT_M0_REGNUM+6, SOFT_M0_REGNUM+7
++
++#define SOFT_M_REGBITS  (((1UL << NUM_M_REGS) - 1) << (SOFT_M0_REGNUM))
++
++/* Number of actual hardware registers.
++   The hardware registers are assigned numbers for the compiler
++   from 0 to just below FIRST_PSEUDO_REGISTER.
++   All registers that the compiler knows about must be given numbers,
++   even those that are not normally considered general registers.
++   Make sure the constant below matches the value of SOFT_M0_REGNUM;
++   for some reason, GCC won't compile if that name is used here directly. */
++#ifdef SOFT_M0_REGNUM
++#if (SOFT_M0_REGNUM != 14)
++#error "bad register numbering"
++#endif
++#endif
++#define FIRST_PSEUDO_REGISTER (14 + NUM_M_REGS)
++
++/* 1 for registers that have pervasive standard uses
++   and are not available for the register allocator.
++   The psuedoregisters (M_REGS) are declared fixed here, but
++   will be unfixed if -msoft-reg-count is seen later.  */
++#define FIXED_REGISTERS \
++    {1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, M_REGS_FIXED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* 1 for registers not available across function calls.
++   These must include the FIXED_REGISTERS and also any
++   registers that can be used without being saved.
++   The latter must include the registers where values are returned
++   and the register where structure-value addresses are passed.
++   Aside from that, you can include as many other registers as you like.  */
++#define CALL_USED_REGISTERS \
++    {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, M_REGS_CALL_USED, }
++  /* -, X, Y, U, S, PC,D, Z, A, B, C, DP,FP,AP,M... */
++
++/* Return number of consecutive hard regs needed starting at reg REGNO
++   to hold something of mode MODE.
++	For the 6809, we distinguish between word-length and byte-length
++	registers. */
++#define HARD_REGNO_NREGS(REGNO, MODE) \
++   (REGSET_CONTAINS_P (REGNO, WORD_REGSET) ? \
++		((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD) : \
++      (GET_MODE_SIZE (MODE)))
++
++
++/* Value is 1 if hard register REGNO can hold a value
++of machine-mode MODE. */
++#define HARD_REGNO_MODE_OK(REGNO, MODE) m6809_hard_regno_mode_ok (REGNO, MODE)
++
++/* Value is 1 if it is a good idea to tie two pseudo registers
++   when one has mode MODE1 and one has mode MODE2.
++   If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
++   for any hard reg, then this must be 0 for correct output.  */
++#define MODES_TIEABLE_P(MODE1, MODE2) 0
++
++/* Specify the registers used for certain standard purposes.
++   The values of these macros are register numbers.  */
++
++/* program counter if referenced as a register */
++#define PC_REGNUM HARD_PC_REGNUM
++
++/* Register to use for pushing function arguments.  */
++#define STACK_POINTER_REGNUM HARD_S_REGNUM
++
++/* Base register for access to local variables of the function.
++ * Before reload, FRAME_POINTER_REGNUM will be used.  Later,
++ * the elimination pass will convert these to STACK_POINTER_REGNUM
++ * if possible, or else HARD_FRAME_POINTER_REGNUM.  The idea is to
++ * avoid tying up a hard register (U) for the frame pointer if
++ * it can be eliminated entirely, making it available for use as
++ * a general register. */
++#define FRAME_POINTER_REGNUM       SOFT_FP_REGNUM
++#define HARD_FRAME_POINTER_REGNUM  HARD_U_REGNUM
++
++/* Define a table of possible eliminations.
++ * The idea is to try to avoid using hard registers for the argument
++ * and frame pointers if they can be derived from the stack pointer
++ * instead, which already has a hard register reserved for it.
++ *
++ * The order of entries in this table will try to convert
++ * ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM into stack pointer
++ * references first, but if that fails, they will be converted to use
++ * HARD_FRAME_POINTER_REGNUM.
++ */
++#define ELIMINABLE_REGS \
++{{ ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
++ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM }}
++
++/* #define CAN_ELIMINATE(FROM, TO) m6809_can_eliminate (FROM, TO) */
++
++/* Define how to offset the frame or argument pointer to turn it
++ * into a stack pointer reference.  This is based on the way that
++ * the frame is constructed in the function prologue. */
++#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
++	(OFFSET) = m6809_initial_elimination_offset (FROM, TO)
++
++/* Base register for access to arguments of the function.
++ * This is only used prior to reload; no instructions will ever
++ * be output referring to this register. */
++#define ARG_POINTER_REGNUM SOFT_AP_REGNUM
++
++/* Register in which static-chain is passed to a function.  */
++#define STATIC_CHAIN_REGNUM HARD_Y_REGNUM
++
++/* #define CONDITIONAL_REGISTER_USAGE (m6809_conditional_register_usage ()) */
++
++/* Order in which hard registers are allocated to pseudos.
++ *
++ * Since the D register is the only valid reg for 8-bit values
++ * now, avoid using it for 16-bit values by putting it after all
++ * other 16-bits.
++ *
++ * Prefer X first since the first 16-bit function argument goes
++ * there.  We may be able to pass in to a subroutine without
++ * a copy.
++ *
++ * Prefer U over Y since instructions using Y take one extra
++ * byte, and thus one extra cycle to execute.
++ */
++#define REG_ALLOC_ORDER \
++   {  HARD_X_REGNUM, HARD_U_REGNUM, HARD_Y_REGNUM, HARD_D_REGNUM, \
++	   HARD_M_REGNUMS, HARD_S_REGNUM, HARD_PC_REGNUM, \
++		HARD_B_REGNUM, HARD_A_REGNUM, HARD_CC_REGNUM, \
++		HARD_DP_REGNUM, SOFT_FP_REGNUM, SOFT_AP_REGNUM, \
++		6, HARD_Z_REGNUM }
++
++/*--------------------------------------------------------------
++	classes of registers
++--------------------------------------------------------------*/
++
++/* Define the classes of registers for register constraints in the
++   machine description.  Also define ranges of constants.
++
++   One of the classes must always be named ALL_REGS and include all hard regs.
++   If there is more than one class, another class must be named NO_REGS
++   and contain no registers.
++
++   The name GENERAL_REGS must be the name of a class (or an alias for
++   another name such as ALL_REGS).  This is the class of registers
++   that is allowed by "g" or "r" in a register constraint.
++   Also, registers outside this class are allocated only when
++   instructions express preferences for them.
++
++   The classes must be numbered in nondecreasing order; that is,
++   a larger-numbered class must never be contained completely
++   in a smaller-numbered class.
++
++   For any two classes, it is very desirable that there be another
++   class that represents their union.  */
++   
++enum reg_class {
++    NO_REGS,    /* The trivial class with no registers in it */
++    D_REGS,     /* 16-bit (word (HI)) data (D) */
++    ACC_A_REGS, /* The A register */
++    ACC_B_REGS, /* The B register */
++	 X_REGS,     /* The X register */
++	 Z_REGS,     /* The Z (zero-bit) register */
++    Q_REGS,     /* 8-bit (byte (QI)) data (A,B) */
++    M_REGS,     /* 8-bit (byte (QI)) soft registers */
++	 CC_REGS,    /* 8-bit condition code register */
++    I_REGS,     /* An index register (A,B,D) */
++    T_REGS,     /* 16-bit addresses, not including stack or PC (X,Y,U) */
++    A_REGS,     /* 16-bit addresses (X,Y,U,S,PC) */
++	 S_REGS,     /* 16-bit soft registers (FP, AP) */
++	 P_REGS,     /* 16-bit pushable registers (D,X,Y,U); omit PC and S */
++    G_REGS,     /* 16-bit data and address (D,X,Y,U,S,PC) */
++    ALL_REGS,   /* All registers */
++    LIM_REG_CLASSES
++};
++
++#define N_REG_CLASSES (int) LIM_REG_CLASSES
++
++/* Since GENERAL_REGS is a smaller class than ALL_REGS,
++   it is not an alias to ALL_REGS, but to G_REGS. */
++#define GENERAL_REGS G_REGS
++
++/* Give names of register classes as strings for dump file.   */
++#define REG_CLASS_NAMES \
++ {  "NO_REGS", "D_REGS", "ACC_A_REGS", "ACC_B_REGS", "X_REGS", "Z_REGS", "Q_REGS", "M_REGS", \
++	 "CC_REGS", "I_REGS", "T_REGS", "A_REGS", "S_REGS", "P_REGS", "G_REGS", \
++	 "ALL_REGS" }
++
++/* Define which registers fit in which classes.
++   This is an initializer for a vector of HARD_REG_SET
++   of length N_REG_CLASSES.  */
++
++#define D_REGSET	(D_REGBIT)
++#define ACC_A_REGSET (A_REGBIT)
++#define ACC_B_REGSET (D_REGBIT)
++#define X_REGSET (X_REGBIT)
++#define Z_REGSET (Z_REGBIT)
++#define Q_REGSET (D_REGBIT | A_REGBIT)
++#define M_REGSET (SOFT_M_REGBITS)
++#define CC_REGSET (CC_REGBIT)
++#define I_REGSET (A_REGBIT | B_REGBIT | D_REGBIT)
++#define T_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT)
++#define A_REGSET (X_REGBIT | Y_REGBIT | U_REGBIT | S_REGBIT | PC_REGBIT)
++#define S_REGSET (SOFT_FP_REGBIT | SOFT_AP_REGBIT)
++#define P_REGSET (D_REGBIT | X_REGBIT | Y_REGBIT | U_REGBIT)
++#define G_REGSET \
++   (D_REGSET | Q_REGSET | I_REGSET | A_REGSET | M_REGSET | S_REGSET)
++#define ALL_REGSET (G_REGSET)
++
++#define REG_CLASS_CONTENTS { \
++	{0}, \
++	{D_REGSET}, \
++   {ACC_A_REGSET}, \
++   {ACC_B_REGSET}, \
++   {X_REGSET}, \
++   {Z_REGSET}, \
++	{Q_REGSET}, \
++	{M_REGSET}, \
++   {CC_REGSET}, \
++	{I_REGSET}, \
++	{T_REGSET}, \
++	{A_REGSET}, \
++	{S_REGSET}, \
++	{P_REGSET}, \
++	{G_REGSET}, \
++	{ALL_REGSET}, \
++}
++
++/* The same information, inverted.
++ * This is defined to use the REG_CLASS_CONTENTS defines above, so that
++ * these two sets of definitions are always consistent. */
++
++#define REGNO_REG_CLASS(REGNO) \
++  (D_REGNO_P (REGNO) ? D_REGS : \
++  (Z_REGNO_P (REGNO) ? Z_REGS : \
++  (ACC_A_REGNO_P (REGNO) ? ACC_A_REGS : \
++  (ACC_B_REGNO_P (REGNO) ? ACC_B_REGS : \
++  (X_REGNO_P (REGNO) ? X_REGS : \
++  (Q_REGNO_P (REGNO) ? Q_REGS : \
++  (M_REGNO_P (REGNO) ? M_REGS : \
++  (CC_REGNO_P (REGNO) ? CC_REGS : \
++  (I_REGNO_P (REGNO) ? I_REGS : \
++  (T_REGNO_P (REGNO) ? T_REGS : \
++  (A_REGNO_P (REGNO) ? A_REGS : \
++  (S_REGNO_P (REGNO) ? S_REGS : \
++  (P_REGNO_P (REGNO) ? P_REGS : \
++  (G_REGNO_P (REGNO) ? G_REGS : ALL_REGS))))))))))))))
++
++#define D_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, D_REGSET))
++#define ACC_A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_A_REGSET))
++#define ACC_B_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, ACC_B_REGSET))
++#define X_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, X_REGSET))
++#define Z_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Z_REGSET))
++#define Q_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, Q_REGSET))
++#define M_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, M_REGSET))
++#define CC_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, CC_REGSET))
++#define I_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, I_REGSET))
++#define T_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, T_REGSET))
++#define A_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, A_REGSET))
++#define S_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, S_REGSET))
++#define P_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, P_REGSET))
++#define G_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, G_REGSET))
++
++/* Macros that test an rtx 'X' to see if it's in a particular
++ * register class.  'X' need not be a REG necessarily. */
++
++#define D_REG_P(X) (REG_P (X) && D_REGNO_P (REGNO (X)))
++#define ACC_A_REG_P(X) (REG_P (X) && ACC_A_REGNO_P (REGNO (X)))
++#define ACC_B_REG_P(X) (REG_P (X) && ACC_B_REGNO_P (REGNO (X)))
++#define X_REG_P(X) (REG_P (X) && X_REGNO_P (REGNO (X)))
++#define Z_REG_P(X) (REG_P (X) && Z_REGNO_P (REGNO (X)))
++#define I_REG_P(X) (REG_P (X) && I_REGNO_P (REGNO (X)))
++#define T_REG_P(X) (REG_P (X) && T_REGNO_P (REGNO (X)))
++#define A_REG_P(X) (REG_P (X) && A_REGNO_P (REGNO (X)))
++#define S_REG_P(X) (REG_P (X) && S_REGNO_P (REGNO (X)))
++#define P_REG_P(X) (REG_P (X) && P_REGNO_P (REGNO (X)))
++#define Q_REG_P(X) (REG_P (X) && Q_REGNO_P (REGNO (X)))
++#define M_REG_P(X) (REG_P (X) && M_REGNO_P (REGNO (X)))
++#define CC_REG_P(X) (REG_P (X) && CC_REGNO_P (REGNO (X)))
++
++/* Redefine this in terms of BYTE_REGSET */
++#define BYTE_REGNO_P(REGNO) (REGSET_CONTAINS_P (REGNO, BYTE_REGSET))
++
++/* The class value for index registers, and the one for base regs.  */
++#define INDEX_REG_CLASS I_REGS
++#define BASE_REG_CLASS A_REGS
++
++/* Get reg_class from a letter in the machine description.  */
++#define REG_CLASS_FROM_LETTER(C) \
++  (((C) == 'a' ? A_REGS : \
++   ((C) == 'd' ? D_REGS : \
++	((C) == 'x' ? I_REGS : \
++	((C) == 't' ? M_REGS : \
++	((C) == 'c' ? CC_REGS : \
++	((C) == 'A' ? ACC_A_REGS : \
++	((C) == 'B' ? ACC_B_REGS : \
++	((C) == 'v' ? X_REGS : \
++	((C) == 'u' ? S_REGS : \
++	((C) == 'U' ? P_REGS : \
++	((C) == 'T' ? T_REGS : \
++	((C) == 'z' ? Z_REGS : \
++   ((C) == 'q' ? Q_REGS : NO_REGS))))))))))))))
++
++/*--------------------------------------------------------------
++   The letters I through O in a register constraint string
++   can be used to stand for particular ranges of immediate operands.
++   This macro defines what the ranges are.
++   C is the letter, and VALUE is a constant value.
++   Return 1 if VALUE is in the range specified by C.
++
++   For the 6809, J, K, L are used for indexed addressing.
++   `I' is used for the constant 1.
++   `J' is used for the 5-bit offsets.
++   `K' is used for the 8-bit offsets.
++   `L' is used for the range of signed numbers that fit in 16 bits.
++   `M' is used for the exact value '8'.
++   `N' is used for the constant -1.
++   `O' is used for the constant 0.
++--------------------------------------------------------------*/
++
++#define CONST_OK_FOR_LETTER_P(VALUE, C) \
++  ((C) == 'I' ? ((VALUE) == 1) : \
++   (C) == 'J' ? ((VALUE) >= -16 && (VALUE) <= 15) : \
++   (C) == 'K' ? ((VALUE) >= -128 && (VALUE) <= 127) : \
++   (C) == 'L' ? ((VALUE) >= -32768 && (VALUE) <= 32767) : \
++   (C) == 'M' ? ((VALUE) == 8) : \
++   (C) == 'N' ? ((VALUE) == -1) : \
++   (C) == 'O' ? ((VALUE) == 0) : 0)
++
++/* Similar, but for floating constants, and defining letters G and H.
++   No floating-point constants are valid on MC6809.  */
++#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
++   ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
++     && VALUE == CONST0_RTX (GET_MODE (VALUE))) : 0)
++
++/* Given an rtx X being reloaded into a reg required to be
++   in class CLASS, return the class of reg to actually use.
++   In general this is just CLASS; but on some machines
++   in some cases it is preferable to use a more restrictive class.  */
++#define PREFERRED_RELOAD_CLASS(X,CLASS) m6809_preferred_reload_class(X,CLASS)
++
++#define SMALL_REGISTER_CLASSES  1
++
++/* Return the maximum number of consecutive registers
++   needed to represent mode MODE in a register of class CLASS.  */
++#define CLASS_MAX_NREGS(CLASS, MODE) \
++    ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
++
++/*--------------------------------------------------------------
++	Stack layout; function entry, exit and calling.
++--------------------------------------------------------------*/
++
++/* Define this if pushing a word on the stack
++   makes the stack pointer a smaller address.  */
++#define STACK_GROWS_DOWNWARD
++
++
++/* Define this if the nominal address of the stack frame
++   is at the high-address end of the local variables;
++   that is, each additional local variable allocated
++   goes at a more negative offset in the frame.  */
++#define FRAME_GROWS_DOWNWARD 1
++
++
++/* Offset within stack frame to start allocating local variables at.
++   If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
++   first local allocated.  Otherwise, it is the offset to the BEGINNING
++   of the first local allocated.  */
++#define STARTING_FRAME_OFFSET 0
++
++
++/* Always push stack arguments for now.  Accumulation is not yet working. */
++#define PUSH_ROUNDING(BYTES) (BYTES)
++
++
++/* Offset of first parameter from the argument pointer register value.
++ * ARG_POINTER_REGNUM is defined to point to the return address pushed
++ * onto the stack, so we must offset by 2 bytes to get to the arguments. */
++#define FIRST_PARM_OFFSET(FNDECL) 2
++
++/* Value is 1 if returning from a function call automatically
++   pops the arguments described by the number-of-args field in the call.
++   FUNTYPE is the data type of the function (as a tree),
++   or for a library call it is an identifier node for the subroutine name. */
++/* #define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0 */
++
++/* Define how to find the value returned by a function.
++   VALTYPE is the data type of the value (as a tree).
++   If the precise function being called is known, FUNC is its FUNCTION_DECL;
++   otherwise, FUNC is 0.  */
++#define FUNCTION_VALUE(VALTYPE, FUNC) m6809_function_value (VALTYPE, FUNC)
++
++/* Define how to find the value returned by a library function
++   assuming the value has mode MODE.  */
++
++/* All return values are in the X-register. */
++#define LIBCALL_VALUE(MODE)  gen_rtx_REG (MODE, HARD_X_REGNUM)
++
++/* Define this if using the nonreentrant convention for returning
++   structure and union values.  No; it is inefficient and buggy. */
++#undef PCC_STATIC_STRUCT_RETURN
++
++/* 1 if N is a possible register number for a function value. */
++#define FUNCTION_VALUE_REGNO_P(N) m6809_function_value_regno_p (N)
++
++/* Define this to be true when FUNCTION_VALUE_REGNO_P is true for
++   more than one register.  */
++#define NEEDS_UNTYPED_CALL 1
++
++/* 1 if N is a possible register number for function argument passing. */
++#define FUNCTION_ARG_REGNO_P(N) \
++	((m6809_abi_version != M6809_ABI_VERSION_STACK) ? \
++   	(((N) == HARD_D_REGNUM) || ((N) == HARD_X_REGNUM)) : \
++		0)
++
++/*--------------------------------------------------------------
++	Argument Lists
++--------------------------------------------------------------*/
++
++/* Cumulative arguments are tracked in a single integer, 
++ * which is the number of bytes of arguments scanned so far,
++ * plus which registers have already been used.  The register
++ * info is kept in some of the upper bits */
++#define CUMULATIVE_ARGS unsigned int
++
++#define CUM_STACK_ONLY 0x80000000
++#define CUM_X_MASK     0x40000000
++#define CUM_B_MASK     0x20000000
++#define CUM_STACK_INVALID 0x10000000
++#define CUM_STACK_MASK 0xFFFFFFF
++
++#define CUM_ADVANCE_8BIT(cum) \
++	(((cum) & CUM_B_MASK) ? (cum)++ : ((cum) |= CUM_B_MASK))
++
++#define CUM_ADVANCE_16BIT(cum) \
++	(((cum) & CUM_X_MASK) ? (cum) += 2 : ((cum) |= CUM_X_MASK))
++
++/* 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.
++	N_NAMED was added in gcc 3.4 and is not used currently. */
++#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT,N_NAMED) \
++	((CUM) = m6809_init_cumulative_args (CUM, FNTYPE, LIBNAME))
++
++#define FUNCTION_ARG_SIZE(MODE, TYPE)	\
++  ((MODE) != BLKmode ? GET_MODE_SIZE (MODE)	\
++   : (unsigned) int_size_in_bytes (TYPE))
++
++/* 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.)  */
++#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
++	 (((MODE == QImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_8BIT (CUM) : \
++	  ((MODE == HImode) && !((CUM) & CUM_STACK_ONLY)) ? \
++		CUM_ADVANCE_16BIT (CUM) : \
++	  ((CUM) = ((CUM) + (TYPE ? int_size_in_bytes (TYPE) : 2))))
++
++/* Define where to put the arguments to a function.
++   Value is zero to push the argument on the stack,
++   or a hard register rtx in which to store the argument.
++	This macro is used _before_ FUNCTION_ARG_ADVANCE.
++
++	For the 6809, the first 8-bit function argument can be placed into B,
++	and the first 16-bit arg can go into X.  All other arguments
++	will be pushed onto the stack.
++
++	Command-line options can adjust this behavior somewhat.
++ */
++#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
++	((MODE == VOIDmode) ? NULL_RTX : \
++	((MODE == BLKmode) || (GET_MODE_SIZE (MODE) > 2)) ? NULL_RTX : \
++	((MODE == QImode) && !((CUM) & (CUM_STACK_ONLY | CUM_B_MASK))) ? \
++		gen_rtx_REG (QImode, HARD_D_REGNUM) : \
++	((MODE == HImode) && !((CUM) & (CUM_STACK_ONLY | CUM_X_MASK))) ?  \
++		gen_rtx_REG (HImode, HARD_X_REGNUM) : m6809_function_arg_on_stack (&CUM))
++
++/* Output assembler code to FILE to increment profiler label # LABELNO
++   for profiling a function entry.  */
++#define FUNCTION_PROFILER(FILE, LABELNO) \
++   fprintf (FILE, "\tldd\t#LP%u\n\tjsr\tmcount\n", (LABELNO));
++
++/* Stack pointer must be correct on function exit */
++#define EXIT_IGNORE_STACK 0
++
++/*****************************************************************************
++**
++** Trampolines for Nested Functions
++**
++*****************************************************************************/
++
++/* Length in units of the trampoline for entering a nested function.  */
++#define TRAMPOLINE_SIZE 7
++
++/*--------------------------------------------------------------
++	Addressing modes,
++	and classification of registers for them.
++--------------------------------------------------------------*/
++
++/* 6809 has postincrement and predecrement addressing modes */
++#define HAVE_POST_INCREMENT  1
++#define HAVE_PRE_DECREMENT  1
++
++/* Whether or not to use index registers is configurable.
++ * Experiments show that things work better when this is off, so
++ * that's the way it is for now. */
++#undef USE_INDEX_REGISTERS
++
++
++/* Macros to check register numbers against specific register classes.  */
++#define REG_VALID_FOR_BASE_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && A_REGNO_P (REGNO))
++
++/* MC6809 index registers do not allow scaling, */
++/* but there is "accumulator-offset" mode. */
++#ifdef USE_INDEX_REGISTERS
++#define REG_VALID_FOR_INDEX_P(REGNO) \
++	(((REGNO) < FIRST_PSEUDO_REGISTER) && I_REGNO_P (REGNO))
++#else
++#define REG_VALID_FOR_INDEX_P(REGNO) 0
++#endif
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_BASE_P (REGNO) \
++	|| (REGNO) == FRAME_POINTER_REGNUM \
++	|| (REGNO) == HARD_FRAME_POINTER_REGNUM \
++	|| (REGNO) == ARG_POINTER_REGNUM \
++	|| (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++/* Internal macro, the nonstrict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_NONSTRICT_P(REGNO) \
++   ((REGNO) >= FIRST_PSEUDO_REGISTER \
++	|| REG_VALID_FOR_INDEX_P (REGNO) \
++	|| (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_BASE_P */
++#define REGNO_OK_FOR_BASE_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_BASE_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_BASE_P (reg_renumber[REGNO])))
++
++
++/* Internal macro, the strict definition for REGNO_OK_FOR_INDEX_P */
++#define REGNO_OK_FOR_INDEX_STRICT_P(REGNO) \
++	((REGNO) < FIRST_PSEUDO_REGISTER ? REG_VALID_FOR_INDEX_P (REGNO) \
++	: (reg_renumber && REG_VALID_FOR_INDEX_P (reg_renumber[REGNO])))
++
++
++#define REGNO_OK_FOR_BASE_P(REGNO) REGNO_OK_FOR_BASE_STRICT_P (REGNO)
++
++#define REGNO_OK_FOR_INDEX_P(REGNO) REGNO_OK_FOR_INDEX_STRICT_P (REGNO)
++
++#define REG_OK_FOR_BASE_STRICT_P(X)     REGNO_OK_FOR_BASE_STRICT_P (REGNO (X))
++#define REG_OK_FOR_BASE_NONSTRICT_P(X)  REGNO_OK_FOR_BASE_NONSTRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_STRICT_P(X)    REGNO_OK_FOR_INDEX_STRICT_P (REGNO (X))
++#define REG_OK_FOR_INDEX_NONSTRICT_P(X) REGNO_OK_FOR_INDEX_NONSTRICT_P (REGNO (X))
++
++#ifndef REG_OK_STRICT
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_NONSTRICT_P(X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_NONSTRICT_P(X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#else
++#define REG_OK_FOR_BASE_P(X)     REG_OK_FOR_BASE_STRICT_P (X)
++#ifdef USE_INDEX_REGISTERS
++#define REG_OK_FOR_INDEX_P(X)    REG_OK_FOR_INDEX_STRICT_P (X)
++#else
++#define REG_OK_FOR_INDEX_P(X)    0
++#endif
++#endif
++
++/* Maximum number of registers that can appear in a valid memory address */
++#ifdef USE_INDEX_REGISTERS
++#define MAX_REGS_PER_ADDRESS 2
++#else
++#define MAX_REGS_PER_ADDRESS 1
++#endif
++
++/* 1 if X is an rtx for a constant that is a valid address.
++ * We allow any constant, plus the sum of any two constants (this allows
++ * offsetting a symbol ref) */
++#define CONSTANT_ADDRESS_P(X) \
++	((CONSTANT_P (X)) \
++	|| ((GET_CODE (X) == PLUS) \
++	      && (CONSTANT_P (XEXP (X, 0))) && (CONSTANT_P (XEXP (X, 1)))))
++
++/* Nonzero if the constant value X is a legitimate general operand.
++   It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.  */
++/* Any single-word constant is ok; the only contexts
++   allowing general_operand of mode DI or DF are movdi and movdf. */
++#define LEGITIMATE_CONSTANT_P(X) (GET_CODE (X) != CONST_DOUBLE)
++
++/* Nonzero if the X is a legitimate immediate operand in PIC mode. */
++#define LEGITIMATE_PIC_OPERAND_P(X)	!symbolic_operand (X, VOIDmode)
++
++/*--------------------------------------------------------------
++	Test for valid memory addresses
++--------------------------------------------------------------*/
++/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
++   that is a valid memory address for an instruction.
++   The MODE argument is the machine mode for the MEM expression
++   that wants to use this address. */
++
++/*--------------------------------------------------------------
++   Valid addresses are either direct or indirect (MEM) versions
++   of the following forms.
++	constant		N
++	register		,X
++	constant indexed	N,X
++	accumulator indexed	D,X
++	auto_increment		,X++
++	auto_decrement		,--X
++--------------------------------------------------------------*/
++
++#define REGISTER_ADDRESS_P(X) \
++  (REG_P (X) && REG_OK_FOR_BASE_P (X))
++
++#define EXTENDED_ADDRESS_P(X) \
++    CONSTANT_ADDRESS_P (X) \
++
++#define LEGITIMATE_BASE_P(X) \
++  ((REG_P (X) && REG_OK_FOR_BASE_P (X))	\
++   || (GET_CODE (X) == SIGN_EXTEND			\
++       && GET_CODE (XEXP (X, 0)) == REG			\
++       && GET_MODE (XEXP (X, 0)) == HImode		\
++       && REG_OK_FOR_BASE_P (XEXP (X, 0))))
++
++#define LEGITIMATE_OFFSET_P(X) \
++    (CONSTANT_ADDRESS_P (X) || (REG_P (X) && REG_OK_FOR_INDEX_P (X)))
++
++/* 1 if X is the sum of a base register and an offset. */
++#define INDEXED_ADDRESS(X) \
++   ((GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 0)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 1))) \
++   || (GET_CODE (X) == PLUS \
++       && LEGITIMATE_BASE_P (XEXP (X, 1)) \
++       && LEGITIMATE_OFFSET_P (XEXP (X, 0))))
++
++#define STACK_REG_P(X) (REG_P(X) && REGNO(X) == HARD_S_REGNUM)
++
++#define STACK_PUSH_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == PRE_DEC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define STACK_POP_P(X) \
++   (MEM_P (X) && GET_CODE (XEXP (X, 0)) == POST_INC && STACK_REG_P (XEXP (XEXP (X, 0), 0)))
++
++#define PUSH_POP_ADDRESS_P(X) \
++    (((GET_CODE (X) == PRE_DEC) || (GET_CODE (X) == POST_INC)) \
++	&& (LEGITIMATE_BASE_P (XEXP (X, 0))))
++
++/* Go to ADDR if X is a valid address. */
++#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
++{ \
++  if (REGISTER_ADDRESS_P(X)) goto ADDR; \
++  if (PUSH_POP_ADDRESS_P (X)) goto ADDR; \
++  if (EXTENDED_ADDRESS_P (X)) goto ADDR; \
++  if (INDEXED_ADDRESS (X)) goto ADDR; \
++  if (MEM_P (X) && REGISTER_ADDRESS_P(XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && PUSH_POP_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && EXTENDED_ADDRESS_P (XEXP (X, 0))) goto ADDR; \
++  if (MEM_P (X) && INDEXED_ADDRESS (XEXP (X, 0))) goto ADDR; \
++}
++
++/*--------------------------------------------------------------
++	Address Fix-up
++--------------------------------------------------------------*/
++/* Go to LABEL if ADDR (a legitimate address expression)
++   has an effect that depends on the machine mode it is used for.
++	In the latest GCC, this case is already handled by the core code
++	so no action is required here. */
++#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) {}
++
++
++/*--------------------------------------------------------------
++	Miscellaneous Parameters
++--------------------------------------------------------------*/
++/* Specify the machine mode that this machine uses
++   for the index in the tablejump instruction.  */
++#define CASE_VECTOR_MODE Pmode
++
++/* Define this as 1 if `char' should by default be signed; else as 0.  */
++#define DEFAULT_SIGNED_CHAR 0
++
++/* This flag, if defined, says the same insns that convert to a signed fixnum
++   also convert validly to an unsigned one.  */
++#define FIXUNS_TRUNC_LIKE_FIX_TRUNC
++
++/* Max number of bytes we can move from memory to memory/register
++   in one reasonably fast instruction.  */
++#define MOVE_MAX 2
++
++/* Int can be 8 or 16 bits (default is 16) */
++#define INT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Short is always 16 bits */
++#define SHORT_TYPE_SIZE (TARGET_BYTE_INT ? 8 : 16)
++
++/* Size (bits) of the type "long" on target machine */
++#define LONG_TYPE_SIZE (TARGET_BYTE_INT ? 16 : 32)
++
++/* Size (bits) of the type "long long" on target machine */
++#define LONG_LONG_TYPE_SIZE 32
++
++/* Size (bits) of the type "char" on target machine */
++#define CHAR_TYPE_SIZE 8
++
++/* Size (bits) of the type "float" on target machine */
++#define FLOAT_TYPE_SIZE 32
++
++/* Size (bits) of the type "double" on target machine.
++ * Note that the C standard does not require that doubles
++ * hold any more bits than float.  Since the 6809 has so few
++ * registers, we cannot really support more than 32-bits. */
++#define DOUBLE_TYPE_SIZE 32 
++
++/* Size (bits) of the type "long double" on target machine */
++#define LONG_DOUBLE_TYPE_SIZE 32
++
++/* Define the type used for "size_t".  With a 64KB address space,
++ * only a 16-bit value here makes sense. */
++#define SIZE_TYPE (TARGET_BYTE_INT ? "long unsigned int" : "unsigned int")
++
++/* Likewise, the difference between two pointers is also a 16-bit
++ * signed value. */
++#define PTRDIFF_TYPE (TARGET_BYTE_INT ? "long int" : "int")
++
++/* Nonzero if access to memory by bytes is slow and undesirable.  */
++#define SLOW_BYTE_ACCESS 0
++
++/* Define if shifts truncate the shift count
++   which implies one can omit a sign-extension or zero-extension
++   of a shift count.  */
++#define SHIFT_COUNT_TRUNCATED 0
++
++/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
++   is done just by pretending it is already truncated.  */
++#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
++
++/* It is as good to call a constant function address as to
++   call an address kept in a register. */
++#define NO_FUNCTION_CSE
++
++/* Specify the machine mode that pointers have.
++   After generation of rtl, the compiler makes no further distinction
++   between pointers and any other objects of this machine mode.  */
++#define Pmode HImode
++
++/* A function address in a call instruction
++   is a byte address (for indexing purposes)
++   so give the MEM rtx a byte's mode.  */
++#define FUNCTION_MODE HImode
++
++/* Define the cost of moving a value from a register in CLASS1
++ * to CLASS2, of a given MODE.
++ *
++ * On the 6809, hard register transfers are all basically equivalent.
++ * But soft register moves are treated more like memory moves. */
++#define REGISTER_MOVE_COST(MODE, CLASS1, CLASS2) \
++	(((CLASS1 == M_REGS) || (CLASS2 == M_REGS)) ? 4 : 7)
++
++/* Define the cost of moving a value between a register and memory. */
++#define MEMORY_MOVE_COST(MODE, CLASS, IN) 5
++
++/* Check a `double' value for validity for a particular machine mode.  */
++
++#define CHECK_FLOAT_VALUE(MODE, D, OVERFLOW) \
++  ((OVERFLOW) = check_float_value (MODE, &D, OVERFLOW))
++
++
++/*--------------------------------------------------------------
++	machine-dependent
++--------------------------------------------------------------*/
++/* Tell final.c how to eliminate redundant test instructions.  */
++
++/* Here we define machine-dependent flags and fields in cc_status
++   (see `conditions.h').  */
++
++/* Store in cc_status the expressions
++   that the condition codes will describe
++   after execution of an instruction whose pattern is EXP.
++   Do not alter them if the instruction would not alter the cc's.  */
++
++/* On the 6809, most of the insns to store in an address register
++   fail to set the cc's.  However, in some cases these instructions
++   can make it possibly invalid to use the saved cc's.  In those
++   cases we clear out some or all of the saved cc's so they won't be used.  */
++
++#define NOTICE_UPDATE_CC(EXP, INSN) \
++  notice_update_cc((EXP), (INSN))
++
++/*****************************************************************************
++**
++** pragma support
++**
++*****************************************************************************/
++
++#if 0
++#define REGISTER_TARGET_PRAGMAS() \
++do { \
++	extern void pragma_section PARAMS ((cpp_reader *)); \
++	c_register_pragma (0, "section", pragma_section); \
++} while (0)
++
++#endif
++
++/*--------------------------------------------------------------
++	ASSEMBLER FORMAT
++--------------------------------------------------------------*/
++
++#define FMT_HOST_WIDE_INT "%ld"
++
++/* Output to assembler file text saying following lines
++   may contain character constants, extra white space, comments, etc.  */
++#define ASM_APP_ON ";----- asm -----\n"
++
++/* Output to assembler file text saying following lines
++   no longer contain unusual constructs.  */
++#define ASM_APP_OFF ";--- end asm ---\n"
++
++/* Use a semicolon to begin a comment. */
++#define ASM_COMMENT_START "; "
++
++/* Output assembly directives to switch to section 'name' */
++#undef TARGET_ASM_NAMED_SECTION
++#define TARGET_ASM_NAMED_SECTION	m6809_asm_named_section
++
++#undef TARGET_HAVE_NAMED_SECTION
++#define TARGET_HAVE_NAMED_SECTION m6809_have_named_section
++
++/* Output before read-only data.  */
++#define TEXT_SECTION_ASM_OP (code_section_op)
++
++/* Output before writable data.  */
++#define DATA_SECTION_ASM_OP (data_section_op)
++
++/* Output before uninitialized data.  */
++#define BSS_SECTION_ASM_OP (bss_section_op)
++
++/* Support the ctors and dtors sections for g++.  */
++ 
++#undef CTORS_SECTION_ASM_OP
++#define CTORS_SECTION_ASM_OP    "\t.area\t.ctors"
++#undef DTORS_SECTION_ASM_OP
++#define DTORS_SECTION_ASM_OP    "\t.area\t.dtors"
++
++
++#undef DO_GLOBAL_CTORS_BODY
++#undef DO_GLOBAL_DTORS_BODY
++
++#define HAS_INIT_SECTION
++
++/* This is how to output an assembler line
++   that says to advance the location counter
++   to a multiple of 2**LOG bytes.  */
++
++#define ASM_OUTPUT_ALIGN(FILE,LOG) \
++  if ((LOG) > 1) \
++    fprintf (FILE, "\t.bndry\t%u\n", 1 << (LOG))
++
++/* The .set foo,bar construct doesn't work by default */
++#undef SET_ASM_OP
++#define ASM_OUTPUT_DEF(FILE, LABEL1, LABEL2) \
++  do { \
++      assemble_name (FILE, LABEL1); \
++      fputs ("\tequ\t", FILE); \
++      assemble_name (FILE, LABEL2); \
++      fputc ('\n', FILE); \
++  } while (0)
++
++/* How to refer to registers in assembler output.
++   This sequence is indexed by compiler's hard-register-number (see above).  */
++#define MNAME(x) [SOFT_M0_REGNUM+(x)] = "*m" C_STRING(x) ,
++
++#define REGISTER_NAMES { \
++	[HARD_D_REGNUM]= "d", \
++	[HARD_X_REGNUM]= "x", \
++	[HARD_Y_REGNUM]= "y", \
++	[HARD_U_REGNUM]= "u", \
++	[HARD_S_REGNUM]= "s", \
++	[HARD_PC_REGNUM]= "pc", \
++	[HARD_A_REGNUM]= "a", \
++	[HARD_B_REGNUM]= "b", \
++	[HARD_CC_REGNUM]= "cc",\
++	[HARD_DP_REGNUM]= "dp", \
++	[SOFT_FP_REGNUM]= "soft_fp", \
++	[SOFT_AP_REGNUM]= "soft_ap", \
++	MNAME(0) MNAME(1) MNAME(2) MNAME(3) \
++	MNAME(4) MNAME(5) MNAME(6) MNAME(7) \
++	[HARD_RSVD1_REGNUM] = "-", \
++	[HARD_Z_REGNUM] = "z" /* bit 2 of CC */ }
++
++/*****************************************************************************
++**
++** Debug Support
++**
++*****************************************************************************/
++
++/* Default to DBX-style debugging */
++#define PREFERRED_DEBUGGING_TYPE DBX_DEBUG
++
++#define DBX_DEBUGGING_INFO
++
++#define DEFAULT_GDB_EXTENSIONS 0
++
++#define ASM_STABS_OP ";\t.stabs\t"
++#define ASM_STABD_OP ";\t.stabd\t"
++#define ASM_STABN_OP ";\t.stabn\t"
++
++#define DBX_CONTIN_LENGTH 54
++
++#define DBX_OUTPUT_MAIN_SOURCE_FILENAME(ASMFILE, FILENAME) \
++do { \
++	const char *p = FILENAME; \
++	while ((p = strchr (p, '/')) != NULL) { \
++		p = FILENAME = p+1; \
++	} \
++  fprintf (ASMFILE, "%s", ASM_STABS_OP); \
++  output_quoted_string (ASMFILE, FILENAME); \
++  fprintf (ASMFILE, ",%d,0,0,", N_SO); \
++  assemble_name (ASMFILE, ltext_label_name); \
++  fputc ('\n', ASMFILE); \
++  switch_to_section (text_section); \
++  (*targetm.asm_out.internal_label) (ASMFILE, "Ltext", 0); \
++} while (0)
++
++/* With -g, GCC sometimes outputs string literals that are longer than
++ * the assembler can handle.  Without actual debug support, these are
++ * not really required.  Redefine the function to output strings to
++ * output as much as possible. */
++#define OUTPUT_QUOTED_STRING(FILE, STR) m6809_output_quoted_string (FILE, STR)
++
++/*****************************************************************************
++**
++** Output and Generation of Labels
++**
++*****************************************************************************/
++
++/* Prefixes for various assembly-time objects */
++
++#define REGISTER_PREFIX ""
++
++#define LOCAL_LABEL_PREFIX ""
++
++#define USER_LABEL_PREFIX "_"
++
++#define IMMEDIATE_PREFIX "#"
++
++/* This is how to output the definition of a user-level label named NAME,
++   such as the label on a static function or variable NAME.  */
++
++#define ASM_OUTPUT_LABEL(FILE,NAME) \
++do { \
++  if (section_changed) { \
++	  fprintf (FILE, "\n%s\n\n", code_section_op); \
++     section_changed = 0; \
++  } \
++  assemble_name (FILE, NAME); \
++  fputs (":\n", FILE); \
++} while (0)
++
++/* This is how to output the label for a function definition.  It
++   invokes ASM_OUTPUT_LABEL, but may examine the DECL tree node for
++	other properties. */
++#define ASM_DECLARE_FUNCTION_NAME(FILE,NAME,DECL) \
++  m6809_declare_function_name (FILE,NAME,DECL)
++
++/* This is how to output a command to make the user-level label
++    named NAME defined for reference from other files.  */
++
++#define GLOBAL_ASM_OP "\n\t.globl\t"
++
++/* This is how to output a reference to a user label named NAME. */
++#define ASM_OUTPUT_LABELREF(FILE,NAME) \
++  fprintf (FILE, "_%s", NAME)
++
++/* This is how to output a reference to a symbol ref
++ * Check to see if the symbol is in the direct page */
++#define ASM_OUTPUT_SYMBOL_REF(FILE,sym) \
++{ \
++	print_direct_prefix (FILE, sym); \
++	assemble_name (FILE, XSTR (sym, 0)); \
++}
++
++/* External references aren't necessary, so don't emit anything */
++#define ASM_OUTPUT_EXTERNAL(FILE,DECL,NAME)
++
++/* This is how to store into the string LABEL
++   the symbol_ref name of an internal numbered label where
++   PREFIX is the class of label and NUM is the number within the class.
++   This is suitable for output with `assemble_name'.  */
++#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
++  sprintf (LABEL, "*%s%lu", PREFIX, (unsigned long int)NUM)
++
++/* This is how to output an assembler line defining an `int' constant.  */
++#define ASM_OUTPUT_INT(FILE,VALUE) \
++( fprintf (FILE, "\t.word\t"), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* Likewise for `char' and `short' constants.  */
++#define ASM_OUTPUT_SHORT(FILE,VALUE) \
++( fprintf (FILE, "\t.word\t"), \
++  output_addr_const (FILE, (VALUE)), \
++  fprintf (FILE, "\n"))
++
++/* This is how to output a string. */ 
++#define ASM_OUTPUT_ASCII(FILE,STR,SIZE) m6809_output_ascii (FILE, STR, SIZE)
++
++/* This is how to output an insn to push a register on the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_PUSH(FILE,REGNO) \
++   fprintf (FILE, "\tpshs\t%s\n", reg_names[REGNO])
++
++/* This is how to output an insn to pop a register from the stack.
++   It need not be very fast code.  */
++
++#define ASM_OUTPUT_REG_POP(FILE,REGNO) \
++   fprintf (FILE, "\tpuls\t%s\n", reg_names[REGNO])
++
++/* This is how to output an element of a case-vector that is absolute. */
++
++#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
++  fprintf (FILE, "\t.word\tL%u\n", VALUE)
++
++/* This is how to output an element of a case-vector that is relative. */
++
++#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
++  fprintf (FILE, "\t.word\tL%u-L%u\n", VALUE, REL)
++
++
++/*****************************************************************************
++**
++** Assembler Commands for Alignment
++**
++*****************************************************************************/
++
++/* ASM_OUTPUT_SKIP is supposed to zero initialize the data. */
++#define ASM_OUTPUT_SKIP(FILE,SIZE) \
++  do { \
++    fprintf (FILE, "\tzmb\t%d\t;skip space\n", SIZE); \
++  } while (0)
++
++/* This says how to output an assembler line
++   to define a global common symbol.  */
++
++#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
++  do { \
++  switch_to_section (bss_section); \
++  fputs ("\n\t.globl\t", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fputs ("\n", FILE); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* This says how to output an assembler line
++   to define a local common symbol.  */
++
++#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
++do { \
++  switch_to_section (bss_section); \
++  assemble_name ((FILE), (NAME)); \
++  fprintf ((FILE), ":\t.blkb\t" FMT_HOST_WIDE_INT "\n", (ROUNDED));} while(0)
++
++/* Store in OUTPUT a string (made with alloca) containing
++   an assembler-name for a local static variable named NAME.
++   LABELNO is an integer which is different for each call.  */
++
++#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
++( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
++  sprintf ((OUTPUT), "%s.%lu", (NAME), (unsigned long int)(LABELNO)))
++
++/* Print an instruction operand X on file FILE.
++   CODE is the code from the %-spec for printing this operand.
++   If `%z3' was used to print operand 3, then CODE is 'z'. */
++#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
++
++/* Print a memory operand whose address is X, on file FILE. */
++#define PRINT_OPERAND_ADDRESS(FILE, ADDR) print_operand_address (FILE, ADDR)
++
++/* Don't let stack pushes build up too much. */
++#define MAX_PENDING_STACK 8
++
++/* Define values for builtin operations */
++enum m6809_builtins
++{
++	M6809_SWI,
++	M6809_SWI2,
++	M6809_SWI3,
++	M6809_CWAI,
++	M6809_SYNC,
++	M6809_ADD_CARRY,
++	M6809_SUB_CARRY,
++	M6809_ADD_DECIMAL,
++	M6809_NOP,
++	M6809_BLOCKAGE
++};
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.md gcc-4.6.4/gcc/config/m6809/m6809.md
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.md	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,2358 @@
++;; GCC machine description for Motorola 6809
++;; Copyright (C) 1989, 2005, 2006, 2007, 2008,
++;; 2009 Free Software Foundation, Inc.
++;;
++;; Mostly by Brian Dominy (brian@oddchange.com) with substantial renovations
++;; by William Astle (lost@l-w.ca).
++;;
++;; Based on earlier work by Tom Jones (jones@sal.wisc.edu) and
++;; Matthias Doerfel (msdoerfe@informatik.uni-erlangen.de)
++;;
++;; 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/>.
++;;
++;; General information:
++;; --------------------
++;; * This backend is mostly a rewrite from earlier (3.1.1 and before)
++;; versions.
++;;
++;; * The 'A' and 'B' registers are treated as a single register by the
++;; register allocator; hence, the instruction templates assume that
++;; both can be modified if either one is available for use.  No
++;; attempt is made to split instructions to refer to a particular half
++;; of the register.  It is always referred to as the 'D' register, even
++;; in QImode (when it will be displayed as 'B').
++;;
++;; * There is full support for proper branch instruction generation,
++;; based on instruction lengths.  However, many instruction patterns
++;; are still overloaded to emit lots of real instructions, which can
++;; make the length calculation difficult; in those cases, I've tried
++;; to be pessimistic and assume the worst-case.
++;;
++;; * The instruction type attributes are only defined for branch
++;; vs. non branch instructions for now, since there is seemingly no
++;; reason to define these for other types anyway.
++;;
++;; * The limited number of total registers presents the greatest
++;; challenge.  There are 'soft registers' -- memory locations
++;; used to simulate real regs -- which can be helpful.
++;;
++;; * Position-independent code (PIC) is supported and has been tested
++;; but not to the extent of absolute code generation.
++;;
++;; * All of the 6809 special opcodes, e.g. SWI and SYNC, are defined
++;; as UNSPEC instructions, and can be accessed from C code using
++;; __builtin_xxxx() style functions.
++;;
++;; What still needs to be done:
++;; ----------------------------
++;; * Replace remaining instances of (define_peephole) with
++;; (define_peephole2), or remove them completely if they are not
++;; matching anyway.  Add more peepholes for things actually encountered.
++;;
++;; * Indexing addressing can lead to crashes in complex functions when
++;; register pressure is high.  Only the 'D' register can actually be
++;; used as an index register, and its demand by other instructions
++;; can sometimes mean that it is impossible to satisfy constraints.
++;; Currently, indexing is completely disabled to avoid these types
++;; of problems, although code is slightly more inefficient in some
++;; working cases.
++;;
++;; * 32-bit math is terribly inefficient.
++;;
++
++
++;;--------------------------------------------------------------------
++;;-  Constants
++;;--------------------------------------------------------------------
++
++;
++; Define constants for hard register numbers.
++;
++(define_constants [
++  (HARD_RSVD1_REGNUM 0)
++  (HARD_X_REGNUM 1) (HARD_Y_REGNUM 2) (HARD_U_REGNUM 3)
++  (HARD_S_REGNUM 4) (HARD_PC_REGNUM 5) (HARD_D_REGNUM 6)
++  (HARD_Z_REGNUM 7)
++  (HARD_A_REGNUM 8) (HARD_B_REGNUM 9)
++  (HARD_CC_REGNUM 10) (HARD_DP_REGNUM 11)
++  (SOFT_FP_REGNUM 12) (SOFT_AP_REGNUM 13)
++  (SOFT_M0_REGNUM 14) (SOFT_M1_REGNUM 15)
++  (SOFT_M2_REGNUM 16) (SOFT_M3_REGNUM 17)
++])
++
++
++;
++; The range in which a short branch insn can be used.
++;
++(define_constants [
++  (MIN_SHORT_BRANCH_OFFSET -127)
++  (MAX_SHORT_BRANCH_OFFSET 128)
++])
++
++
++;
++; The lengths of various types of real 6809 instructions.
++;
++; By default, ordinary insns are 4 bytes long.  This is often not
++; right, and the insn patterns below will redefine this to the
++; correct value.
++;
++; Branch instruction lengths (conditional and unconditionals) are
++; well known and declared here.  The short insns are used when the
++; offset is within the range declared above (between MIN_SHORT
++; and MAX_SHORT) ; otherwise the long form is used.
++;
++(define_constants [
++  (DEFAULT_INSN_LENGTH 4)
++  (SHORT_CBRANCH_LENGTH 2)
++  (LONG_CBRANCH_LENGTH 4)
++  (SHORT_BRANCH_LENGTH 2)
++  (LONG_BRANCH_LENGTH 3)
++])
++
++
++;
++; Constants for insn cycle counts.
++; Note that these counts all assume 1-byte opcodes.  2-byte
++; opcodes require 1 extra cycles for fetching the extra byte.
++;
++(define_constants [
++  ;; The default insn length, when it cannot be calculated.
++  ;; Take a conservative approach and estimate high.
++  (DEFAULT_INSN_CYCLES 10)
++
++  ;; Cycle counts for ALU and load operations.
++  (ALU_INHERENT_CYCLES 2)
++  (ALU_IMMED_CYCLES 2)
++  (ALU_DIRECT_CYCLES 4)
++  (ALU_INDEXED_BASE_CYCLES 4)
++  (ALU_EXTENDED_CYCLES 5)
++
++  ;; If an ALU operation is on a 16-bit register (D), then
++  ;; add this number of cycles to the total count.
++  (ALU_16BIT_CYCLES 2)
++
++  ;; A load of a 16-bit register incurs this extra amount.
++  (LOAD_16BIT_CYCLES 1)
++
++  ;; Cycle counts for memory-only operations (bit shifts, clear, test)
++  (MEM_DIRECT_CYCLES 6)
++  (MEM_INDEXED_BASE_CYCLES 6)
++  (MEM_EXTENDED_CYCLES 7)
++
++  ;; Cycle count for any reg-reg transfer (regardless of size)
++  (EXG_CYCLES 8)
++  (TFR_CYCLES 6)
++
++  ;; Cycle count for a condition code update (andcc/orcc)
++  (CC_CYCLES 3)
++
++  (JMP_DIRECT_CYCLES 3)
++  (JMP_INDEXED_BASE_CYCLES 3)
++  (JMP_EXTENDED_CYCLES 4)
++
++  (JSR_DIRECT_CYCLES 7)
++  (JSR_INDEXED_BASE_CYCLES 7)
++  (JSR_EXTENDED_CYCLES 8)
++
++  (LEA_BASE_CYCLES 4)
++
++  ;; Cycle count for a psh/pul operations.  Add to this the
++  ;; total number of bytes moved for the correct count.
++  (PSH_PUL_CYCLES 5)
++
++  ;; Miscellaneous cycle counts
++  (CWAI_CYCLES 20)
++  (MUL_CYCLES 11)
++  (NOP_CYCLES 2)
++  (RTI_CYCLES 15)
++  (RTS_CYCLES 5)
++  (SWI_CYCLES 20)
++  (SYNC_CYCLES 4)
++])
++
++
++;
++; An enumeration of values for each "unspec"; i.e. unspecified
++; instruction.  These represent insns that are meaningful on the
++; 6809 but which have no intrinsic meaning to GCC itself.
++; These insns can be generated explicitly using the __builtin_xxx
++; syntax; they are also implicitly generated by the backend
++; as needed to implement other insns.
++;
++(define_constants [
++  (UNSPEC_BLOCKAGE 0)
++  (UNSPEC_PUSH_RS 1)
++  (UNSPEC_POP_RS 2)
++  (UNSPEC_SWI 3)
++  (UNSPEC_CWAI 4)
++  (UNSPEC_ADD_CARRY 5)
++  (UNSPEC_SUB_CARRY 6)
++  (UNSPEC_SYNC 7)
++  (UNSPEC_ADD_DECIMAL 8)
++])
++
++
++;;--------------------------------------------------------------------
++;;-  Predicates
++;;--------------------------------------------------------------------
++
++(include "predicates.md")
++
++;;--------------------------------------------------------------------
++;;-  Attributes
++;;--------------------------------------------------------------------
++
++;;
++;; The type attribute is used to distinguish between different
++;; types of branch instructions, so that their lengths can be
++;; calculated correctly.
++;;
++(define_attr "type" "branch,cbranch,unknown" (const_string "unknown"))
++
++;;
++;; The length of a branch instruction is calculated based on how
++;; far away the branch target is.  Lengths of other insns default
++;; to 4.  set_attr is used in instruction templates to specify
++;; the length when it is known exactly.  When not sure, err on
++;; the high side to avoid compile errors.
++;;
++(define_attr "length" ""
++  (cond [
++    (eq_attr "type" "branch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_BRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_BRANCH_LENGTH)
++          (const_int SHORT_BRANCH_LENGTH)))
++    (eq_attr "type" "cbranch")
++    (if_then_else (lt (minus (match_dup 0) (pc))
++                      (const_int MIN_SHORT_BRANCH_OFFSET))
++      (const_int LONG_CBRANCH_LENGTH)
++        (if_then_else (gt (minus (match_dup 0) (pc))
++                          (const_int MAX_SHORT_BRANCH_OFFSET))
++          (const_int LONG_CBRANCH_LENGTH)
++          (const_int SHORT_CBRANCH_LENGTH)))
++  ] (const_int DEFAULT_INSN_LENGTH)))
++
++
++;;
++;; The default attributes for 'asm' statements.
++;; The default length is the longest possible single 6809 instruction,
++;; which is 5 bytes.  GCC will automatically multiply this by the
++;; number of real insns contained in an asm statement.
++;;
++(define_asm_attributes
++  [(set_attr "length" "5")
++   (set_attr "type" "unknown")])
++
++;;
++;; An attribute for the number of cycles that it takes an instruction
++;; to execute.
++;;
++(define_attr "cycles" "" (const_int DEFAULT_INSN_CYCLES))
++
++
++;;--------------------------------------------------------------------
++;;- Instruction patterns.  When multiple patterns apply,
++;;- the first one in the file is chosen.
++;;-
++;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
++;;-
++;;- Note: NOTICE_UPDATE_CC in m6809.h handles condition code updates
++;;- for most instructions.
++;;--------------------------------------------------------------------
++
++;;--------------------------------------------------------------------
++;;-  Test
++;;--------------------------------------------------------------------
++
++;; cmpx is 3 bytes, not 4
++(define_insn "*tsthi_x"
++  [(set (cc0) (match_operand:HI 0 "register_operand_x" "v"))]
++  ""
++  "cmpx\t#0"
++  [(set_attr "length" "3")])
++
++;; subd #0 is 3 bytes, better than cmpd #0 which is 4 bytes
++(define_insn "*tsthi_d"
++  [(set (cc0) (match_operand:HI 0 "register_operand_d" "d"))]
++  ""
++  "subd\t#0"
++  [(set_attr "length" "3")])
++
++(define_insn "*tsthi"
++  [(set (cc0) (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "cmp%0\t#0"
++   [(set_attr "length" "4")])
++
++(define_insn "*bitqi3"
++  [(set (cc0)
++    (and:QI (match_operand:QI 0 "register_operand" "%q")
++      (match_operand:QI 1 "general_operand" "mi")))]
++  ""
++  "bit%0\t%1"
++  [(set_attr "length" "3")])
++
++
++(define_insn "tstqi"
++  [(set (cc0) (match_operand:QI 0 "nonimmediate_operand" "q,mt"))]
++  ""
++  "@
++   tst%0
++   tst\t%0"
++   [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Compare instructions
++;;--------------------------------------------------------------------
++
++;; - cmphi for register to memory or register compares
++(define_insn "cmphi"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 0 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 1 "general_operand" "mi, da,  dU")))]
++  ""
++{
++  if ((REG_P (operands[0])) && (REG_P (operands[1]))) {
++    output_asm_insn ("pshs\t%1\t;cmphi: R:%1 with R:%0", operands);
++    return "cmp%0\t,s++\t;cmphi:";
++  }
++  if (GET_CODE (operands[0]) == REG)
++    return "cmp%0\t%1\t;cmphi:";
++  else {
++    cc_status.flags |= CC_REVERSED;
++    return "cmp%1\t%0\t;cmphi:(R)";
++  }
++}
++  [(set_attr "length" "5,5,7")])
++
++
++(define_insn "cmpqi"
++  [(set (cc0)
++    (compare (match_operand:QI 0 "whole_general_operand" "q,q, q,O,mt,K")
++    (match_operand:QI 1 "whole_general_operand"          "O,mt,K,q,q, q")))]
++  ""
++{
++    if (REG_P (operands[0]) && !M_REG_P (operands[0]))
++    {
++      if (operands[1] == const0_rtx)
++        return "tst%0\t;cmpqi:(ZERO)";
++      else
++        return "cmp%0\t%1\t;cmpqi:";
++    }
++    else
++    {
++      cc_status.flags |= CC_REVERSED;
++
++      if (operands[0] == const0_rtx)
++        return "tst%1\t;cmpqi:(RZERO)";
++      else
++        return "cmp%1\t%0\t;cmpqi:(R)";
++    }
++}
++   [(set_attr "length" "1,3,2,1,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- Compare/branch pattern
++;;--------------------------------------------------------------------
++
++(define_expand "cbranchhi4"
++  [(set (cc0)
++    (compare
++      (match_operand:HI 1 "general_operand" "da, mi, ??Ud")
++      (match_operand:HI 2 "general_operand" "mi, da,  dU")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++(define_expand "cbranchqi4"
++  [(set (cc0)
++    (compare
++      (match_operand:QI 1 "whole_general_operand" "q,q, q,O,mt,K")
++      (match_operand:QI 2 "whole_general_operand" "O,mt,K,q,q, q")))
++   (set (pc)
++     (if_then_else
++        (match_operator 0 "ordered_comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 3 "" ""))
++        (pc)))]
++   ""
++   ""
++)
++
++;;--------------------------------------------------------------------
++;;-  Move
++;;--------------------------------------------------------------------
++
++; this looks good (obviously not finished) but I still see 'movsi'
++; places in udivsi3 where it's broken
++; (define_insn "pushsi1"
++;   [(set (mem:SI (pre_dec (reg:HI HARD_S_REGNUM)))
++;         (match_operand:SI 0 "general_operand" "o"))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int -4))) ]
++;   ""
++;   "; pushsi %0"
++;    [(set_attr "length" "12")])
++;
++; (define_insn "popsi1"
++;   [(set (match_operand:SI 0 "general_operand" "=o")
++;         (mem:SI (post_inc (reg:HI HARD_S_REGNUM))))
++;    (set (reg:HI HARD_S_REGNUM)
++;         (plus:HI (reg:HI HARD_S_REGNUM) (const_int 4))) ]
++;   ""
++;   "; popsi %0"
++;    [(set_attr "length" "12")])
++
++; (define_insn "movsi"
++;   [(set (match_operand:SI 0 "nonimmediate_operand" "=o")
++;         (match_operand:SI 1 "general_operand"      " oi"))]
++;   ""
++;   "; movsi %0 <- %1"
++;    [(set_attr "length" "1")])
++
++; this doesn't work
++; (define_expand "movsi"
++;   [(parallel [
++;      (set (match_operand:SI 0 "nonimmediate_operand" "")
++;           (match_operand:SI 1 "general_operand" ""))
++;      (clobber (match_scratch:HI 2 ""))])]
++;   ""
++; {
++;   rtx insn;
++;   if (STACK_PUSH_P (operands[0]) || STACK_POP_P (operands[1]))
++;   {
++;     REG_NOTES (insn) = alloc_EXPR_LIST (REG_INC, stack_pointer_rtx, REG_NOTES (insn));
++;   }
++;   insn = emit_move_multi_word (SImode, operands[0], operands[1]);
++;   DONE;
++; })
++
++
++(define_expand "movhi"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++{
++  /* One of the ops has to be in a register prior to reload */
++  if (!register_operand (operand0, HImode) &&
++      !register_operand (operand1, HImode))
++    operands[1] = copy_to_mode_reg (HImode, operand1);
++})
++
++;;; Try a splitter to handle failure cases where we try to move
++;;; an immediate constant (zero usually) directly to memory.
++;;; This absolutely requires an intermediate register.
++(define_split
++  [(set (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "immediate_operand"  ""))
++   (clobber (match_operand:HI 2 "register_operand" ""))]
++  ""
++  [(set (match_dup 2) (match_dup 1))
++   (set (match_dup 0) (match_dup 2))]
++  "")
++
++
++;;; This would be a nice method for loading from a word array,
++;;; but it is never generated because the combiner cannot merge
++;;; more than 3 instructions (there are four here).  This is
++;;; perhaps better done via a peephole.
++(define_insn "*movhi_array_load"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=da")
++    (mem:HI (plus:HI (ashift:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B")) (const_int 1))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;abx\;ld%0\t,x"
++   [(set_attr "length" "7")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movhi_push"
++  [(set (match_operand:HI 0 "push_operand" "=m")
++    (match_operand:HI 1 "register_operand" "U"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++(define_insn "*movhi_pic_symbolref"
++  [(set (match_operand:HI 0 "register_operand" "=a")
++    (match_operand:HI 1 "symbolic_operand" ""))]
++  "flag_pic"
++  "lea%0\t%c1,pcr"
++   [(set_attr "length" "4")])
++
++
++(define_insn "*movhi_1"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=a,d,a,ad,mu")
++    (match_operand:HI 1 "general_operand"          " a,a,d,miu,ad"))]
++  ""
++  "@
++   lea%0\t,%1
++   tfr\t%1,%0
++   tfr\t%1,%0
++   ld%0\t%1
++   st%1\t%0"
++   [(set_attr "length" "2,2,2,*,*")])
++
++
++;;; Generated by the combiner to merge an address calculation with
++;;; a byte load.  We can use the 'abx' instruction here.
++(define_insn "*movqi_array_load"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (mem:QI (plus:HI (zero_extend:HI (match_operand:QI 1 "register_operand" "%B"))
++                     (match_operand:HI 2 "immediate_operand" "i"))))
++   (clobber (match_scratch:HI 3 "=X"))]
++  ""
++  "ldx\t%2\;abx\;ld%0\t,x"
++   [(set_attr "length" "6")])
++
++
++;;; Optimize the move of a byte to the stack using the pshs instruction
++;;; instead of a store with pre-increment.
++(define_insn "movqi_push"
++  [(set (match_operand:QI 0 "push_operand" "=m")
++    (match_operand:QI 1 "register_operand" " q"))]
++  ""
++  "pshs\t%1"
++  [(set_attr "length" "2")])
++
++
++;;; Optimize the move of a byte from the stack using the puls instruction
++;;; instead of a store with post-decrement.
++(define_insn "movqi_pop"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (match_operand:QI 1 "pop_operand" "m"))]
++  ""
++  "puls\t%0"
++  [(set_attr "length" "2")])
++
++
++;;- load low byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_lsb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,m,a,d, U") 1))]
++  ""
++  "@
++   \t;movlsbqihi: D->B
++   ld%0\t%L1\t;movlsbqihi: msb:%1 -> R:%0
++   tfr\t%1,d\t;movlsbqihi: R:%1 -> R:%0
++   stb\t%0\t;movlsbqihi: R:%1 -> %0
++   pshs\t%1\t;movlsbqihi: R:%1 -> R:%0\;leas\t1,s\;puls\t%0"
++   [(set_attr "length" "0,*,2,*,6")])
++
++
++;;- load high byte of 16-bit data into 8-bit register/memory
++(define_insn "*mov_msb"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,q,q,q,m,!q")
++      (subreg:QI (match_operand:HI 1 "general_operand" "d,O,a,m,d, U") 0))]
++  ""
++  "@
++   tfr\ta,b\t;movmsbqihi: D->B
++   clr%0\t\t;movmsbqihi: ZERO -> R:%0
++   tfr\t%1,d\t;movmsbqihi: R:%1 -> R:%0\;tfr\ta,b
++   ld%0\t%L1\t;movmsbqihi: lsb:%1 -> R:%0
++   sta\t%0\t;movmsbqihi: R:%1 -> %0
++   pshs\t%1\t;movmsbqihi: R:%1 -> R:%0\;puls\t%0\;leas\t1,s"
++  [(set_attr "length" "2,1,4,*,*,6")])
++
++
++(define_insn "*movqi_boolean"
++  [(set (reg:QI HARD_Z_REGNUM)
++    (match_operand:QI 0 "general_operand" "q,O,i,m"))]
++  ""
++  "@
++   tst%0
++   andcc\t#~4
++   orcc\t#4
++   tst\t%0")
++
++
++(define_insn "movqi"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q,m,q,m,q,z")
++    (match_operand:QI 1 "general_operand"          " q,O,O,mi,q,z,q"))]
++  ""
++  "@
++   tfr\t%1,%0
++   clr%0
++   clr\t%0
++   ld%0\t%1
++   st%1\t%0
++   tfr\tcc,%0\;and%0\t#4
++   tst%0"
++   [(set_attr "length" "2,1,3,*,*,4,1")])
++
++
++;;--------------------------------------------------------------------
++;;-  Swap registers
++;;--------------------------------------------------------------------
++
++; Note: 8-bit swap is never needed so it is not defined.
++
++(define_insn "swaphi"
++  [(set (match_operand:HI 0 "register_operand" "+r")
++    (match_operand:HI 1 "register_operand" "+r"))
++   (set (match_dup 1) (match_dup 0))]
++  ""
++  "exg\t%1,%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int EXG_CYCLES))])
++
++
++(define_insn "bswaphi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (bswap:HI (match_operand:HI 1 "register_operand" "0")))]
++  ""
++  "exg\ta,b"
++  [(set_attr "length" "2")])
++
++
++;;--------------------------------------------------------------------
++;;-  Extension and truncation insns.
++;;--------------------------------------------------------------------
++
++(define_insn "extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (sign_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "sex\t\t;extendqihi2: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++(define_insn "zero_extendqihi2"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++        (zero_extend:HI (match_operand:QI 1 "general_operand" "B")))]
++  ""
++  "clra\t\t;zero_extendqihi: R:%1 -> R:%0"
++  [(set_attr "length" "1")])
++
++
++;;--------------------------------------------------------------------
++;;- All kinds of add instructions.
++;;--------------------------------------------------------------------
++
++
++;;
++;; gcc's automatic version of addsi3 doesn't know about adcb,adca
++;; so it is MUCH less efficient.  Define this one ourselves.
++;;
++;; TODO - can't always get 'd' for the clobber... allow other registers
++;; as well and use exg d,R ... exg R,d around the code sequence to
++;; use others, at a price.  Also consider libcall for this when
++;; optimizing for size.
++;;
++(define_insn "addsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (plus:SI (match_operand:SI 1 "general_operand" "%o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (PLUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++; Increment of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int 1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("inc\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("inc\t%0\;__IL%=:", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Decrement of a 16-bit MEM by 1 can be done without a register.
++(define_insn "*addhi_mem_minus1"
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++        (plus:HI (match_dup 0) (const_int -1)))]
++   "GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF"
++{
++  rtx xoperands[2];
++
++  xoperands[0] = operands[0];
++  xoperands[1] = adjust_address (operands[0], QImode, 1);
++
++  output_asm_insn ("tst\t%1", xoperands);
++  output_asm_insn ("bne\t__IL%=", xoperands);
++  output_asm_insn ("dec\t%0", xoperands);
++  output_asm_insn ("__IL%=:", xoperands);
++  output_asm_insn ("dec\t%1", xoperands);
++  return "";
++}
++  [(set_attr "length" "7")])
++
++
++; Allow the addition of an 8-bit quantity to a 16-bit quantity
++; using the LEAX B,Y addressing mode, where X and Y are both
++; index registers.  This will only get generated via the peephole
++; which removes a sign extension.
++(define_insn "*addhi_b"
++  [(set (match_operand:HI 0 "index_register_operand"       "=a")
++    (plus:HI(match_operand:HI 1 "index_register_operand"   "%a")
++    (match_operand:QI 2 "register_operand"                  "q")
++  ))]
++  ""
++  "lea%0\t%2,%1\t;addhi_b: R:%0 = R:%2 + R:%1"
++  [(set_attr "length" "*")])
++
++
++; Splitter for addhi pattern #5 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "memory_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   (set (reg:HI HARD_D_REGNUM)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 1)))
++   (parallel [(set (match_dup 0) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 0))])
++   ]
++{
++})
++
++
++; Splitter for addhi pattern #7 below
++(define_split
++  [(set (match_operand:HI 0 "index_register_operand" "")
++    (plus:HI (match_dup 0) (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed"
++  [
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   (set (match_dup 0)
++        (plus:HI (reg:HI HARD_D_REGNUM) (match_dup 0)))
++   (parallel [(set (match_dup 1) (reg:HI HARD_D_REGNUM))
++              (set (reg:HI HARD_D_REGNUM) (match_dup 1))])
++   ]
++{
++})
++
++
++; TODO - this is ugly.  During RTL generation, we don't know what registers
++; are available, so the multiple-insn sequences can only be solved
++; via 'define_split's during matching.  See andhi3 for an example.
++; Keep the constraints with ? modifiers to help reload pick the right
++; registers.
++;
++; The forms are:
++; 1. D += D, expand this into a shift instead. (rtx costs should be corrected
++; to avoid this even happening...)
++; 2. D += U, require U to be pushed to memory.  (Lots of patterns do this
++; now, is this a better way?)
++; 3. Best choice: 'addd'
++; 4. Next best choice: 'lea'
++; 5. Hybrid of 3 and 4
++; 6. Same as 4, not bad
++; 7. BAD, no D register at all
++; 8. 'lea', as good as 4.
++(define_insn "addhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand"      "=d, d,  d,  a,?a, a,???T,a")
++    (plus:HI(match_operand:HI 1 "add_general_operand"   "%0, 0,  0,  d, 0, a, 0, a")
++    (match_operand:HI 2 "general_operand"               " 0, !U, mi, a, m, d, T, i")
++  ))]
++  ""
++  "@
++   lslb\t\t;addhi: R:%0 += R:%2\;rola\t\t;also R:%0 *= 2
++   pshs\t%2\t;addhi: R:%0 += R:%2\;add%0\t,s++
++   add%0\t%2
++   lea%0\t%1,%2
++   #
++   lea%0\t%2,%1
++   #
++   lea%0\t%a2,%1"
++   [(set_attr "length" "2,6,*,*,7,*,7,*")])
++
++
++(define_insn "addqi3_carry"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_ADD_CARRY))]
++  ""
++  "adc%0\t%2\t;addqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++; TODO: specifying 'A' for the first constraint, to force into the A register
++; is not working because of the way registers are currently set up.  This will
++; take some work to get right.  Thus the second alternative as a backup.
++(define_insn "addqi3_decimal"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=A,?q")
++    (unspec:QI [
++      (match_operand:QI 1 "general_operand"        "%0,0")
++      (match_operand:QI 2 "general_operand"        "mi,mi")] UNSPEC_ADD_DECIMAL))]
++  ""
++  "@
++   adda\t%2\;daa
++   tfr\t%0,a\;adda\t%2\;daa\;tfr\ta,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "addqi3"
++  [(set (match_operand:QI 0 "nonimmediate_operand"       "=q,q,q,m,m,q")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "%0,0,0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " 0,I,N,I,N,mi")))]
++  ""
++  "@
++   asl%0\t\t;addqi: R:%0 = R:%0 + R:%0
++   inc%0
++   dec%0
++   inc\t%0
++   dec\t%0
++   add%0\t%2"
++  [(set_attr "length" "1,1,1,3,3,*")])
++
++
++;;--------------------------------------------------------------------
++;;- Subtract instructions.
++;;--------------------------------------------------------------------
++
++(define_insn "subsi3"
++  [(set (match_operand:SI 0 "nonimmediate_operand"  "=o")
++     (minus:SI (match_operand:SI 1 "general_operand" " o")
++        (match_operand:SI 2 "general_operand"       " oi")))
++   (clobber (match_scratch:HI 3 "=d"))]
++  ""
++{
++  m6809_output_addsi3 (MINUS, operands);
++  return "";
++}
++  [(set_attr "length" "21")])
++
++
++(define_insn "subhi3"
++  [(set (match_operand:HI 0 "register_operand"      "=d,  d, a")
++    (minus:HI (match_operand:HI 1 "register_operand" "0,  0, 0")
++    (match_operand:HI 2 "general_operand"            "mi, ?U,n")))]
++  ""
++  "@
++   sub%0\t%2\t;subhi: R:%0 -= %2
++   pshs\t%2\t;subhi: R:%0 -= R:%2\;sub%0\t,s++
++   lea%0\t%n2,%1\t;subhi: R:%0 = R:%1 + %n2"
++   [(set_attr "length" "*,5,3")])
++
++
++(define_insn "subqi3_carry"
++  [(set (match_operand:QI 0 "register_operand" "=q")
++    (unspec:QI [
++      (match_operand:QI 1 "whole_general_operand" "%0")
++      (match_operand:QI 2 "whole_general_operand" "tmi")] UNSPEC_SUB_CARRY))]
++  ""
++  "sbc%0\t%2\t;subqi_carry: R:%0 += %2"
++  [(set_attr "length" "*")])
++
++
++(define_insn "subqi3"
++  [(set (match_operand:QI 0 "register_operand"            "=q, q, !q, q")
++    (minus:QI (match_operand:QI 1 "whole_register_operand" "0, 0,  I, 0")
++    (match_operand:QI 2 "whole_general_operand"            "I, mi, 0, t")))]
++  ""
++  "@
++   dec%0
++   sub%0\t%2
++   dec%0\;neg%0
++   sub%0\t%2"
++   [(set_attr "length" "1,3,2,3")])
++
++
++;;--------------------------------------------------------------------
++;;- Multiply instructions.
++;;--------------------------------------------------------------------
++
++; TODO - merge these two instructions, using 'extend_operator' to match
++; either signed or zero extension.  Everything else is the same.
++(define_insn "mulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++      (mult:HI (sign_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++      (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;mulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++(define_insn "umulqihi3"
++   [(set (match_operand:HI 0 "register_operand" "=d")
++    (mult:HI (zero_extend:HI (match_operand:QI 1 "general_operand" "%q"))
++    (match_operand:QI 2 "general_operand" "tmK")))]
++  ""
++  "lda\t%2\t;umulqihi3\;mul"
++  [(set_attr "length" "3")])
++
++
++; Expand a 16x16 multiplication into either a libcall or a shift.
++; If the second operand is a small constant, use the above form.
++; Otherwise, do a libcall.
++(define_expand "mulhi3"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++    (mult:HI (match_operand:HI 1 "general_operand" "")
++    (match_operand:HI 2 "nonmemory_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "mulhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- Divide instructions.
++;;--------------------------------------------------------------------
++
++(define_expand "divhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (div:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "divhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "divqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (div:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "divqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "udivhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++     (udiv:HI (match_operand:HI 1 "register_operand" "")
++              (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "udivhi3", operands, 2);
++  DONE;
++})
++
++
++;;--------------------------------------------------------------------
++;;- mod
++;;--------------------------------------------------------------------
++
++(define_expand "modhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (mod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "modhi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "modqi3"
++  [(set (match_operand:QI 0 "register_operand" "")
++    (mod:QI (match_operand:QI 1 "register_operand" "")
++    (match_operand:QI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (QImode, "modqi3", operands, 2);
++  DONE;
++})
++
++
++(define_expand "umodhi3"
++  [(set (match_operand:HI 0 "register_operand" "")
++    (umod:HI (match_operand:HI 1 "register_operand" "")
++    (match_operand:HI 2 "register_operand" "")))]
++  ""
++{
++  emit_libcall_insns (HImode, "umodhi3", operands, 2);
++  DONE;
++})
++
++
++
++;;--------------------------------------------------------------------
++;;- and, or, xor common patterns
++;;--------------------------------------------------------------------
++
++; Split a bitwise HImode into two QImode instructions, with one of
++; the sources in a pushable register.  The register is pushed onto
++; the stack and memory pop operands (,s+) are used in the QI forms.
++(define_split
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "register_operand" "")]))]
++  "reload_completed"
++  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 2))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (reg:HI HARD_S_REGNUM)))]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++})
++
++; Split a bitwise HImode into two QImode instructions, with one
++; of the sources being a (MEM (MEM (...)); i.e. an indirect memory
++; reference.  This requires dereferencing the pointer into a
++; temporary register (X), which must be saved/restored around the
++; compute instructions.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (mem:HI (match_operand:HI 2 "memory_operand" ""))]))]
++  "reload_completed"
++  [
++   (set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 4))
++   (set (match_dup 4) (match_dup 2))
++   (set (match_dup 4) (mem:HI (match_dup 4)))
++   (set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_A_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++         [(reg:QI HARD_D_REGNUM)
++          (mem:QI (post_inc:QI (match_dup 4)))]))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (match_dup 4) (mem:HI (post_inc:HI (reg:HI HARD_S_REGNUM))))
++   ]
++{
++  /* Use X for a temporary index register */
++  operands[4] = gen_rtx_REG (HImode, HARD_X_REGNUM);
++})
++
++
++; Split a bitwise HImode into two QImode instructions.  This is
++; the common case.  This handles splitting when neither of the
++; above two cases applies.
++(define_split 
++  [(set (match_operand:HI 0 "register_operand" "")
++    (match_operator:HI 3 "logical_bit_operator"
++      [(match_operand:HI 1 "register_operand" "")
++       (match_operand:HI 2 "general_operand" "")]))]
++  "reload_completed"
++  [(set (reg:QI HARD_A_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_A_REGNUM) (match_dup 4)]))
++   (set (reg:QI HARD_D_REGNUM) (match_op_dup:QI 3
++      [(reg:QI HARD_D_REGNUM) (match_dup 5)]))
++   (use (reg:QI HARD_A_REGNUM))]
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[4] = gen_rtx_const_high (operands[2]);
++    operands[5] = gen_rtx_const_low (operands[2]);
++  }
++  else if ((GET_CODE (operands[2]) == MEM)
++    && (GET_CODE (XEXP (operands[2], 0)) == MEM))
++  {
++    FAIL;
++  }
++  else
++  {
++    operands[4] = gen_highpart (QImode, operands[2]);
++    operands[5] = gen_lowpart (QImode, operands[2]);
++  }
++})
++
++; Below are the specific cases for each of the operators.
++; The QImode versions are the simplest and can be implemented
++; directly on the hardware.  The HImode cases are all output
++; using one of the above splitting techniques.
++
++;;--------------------------------------------------------------------
++;;- and
++;;--------------------------------------------------------------------
++
++(define_insn "andhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (and:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++;; it is not clear that this is correct
++(define_insn "*andqi_2"
++  [(set
++   (match_operand:QI 0 "register_operand" "=q")
++   (and:QI (match_operand:QI 1 "register_operand" "q")
++     (match_operand 2 "const_int_operand" "i")))]
++  ""
++{
++  if (GET_CODE (operands[2]) == CONST_INT)
++  {
++    operands[3] = GEN_INT(INTVAL(operands[2]) & 0xff);
++    return "and%0\t%3";
++  }
++
++  return "and%0\t%2";
++}
++  [(set_attr "length" "2")])
++
++(define_insn "andqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,qc")
++    (and:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   clr%0\t;andqi(ZERO)
++   \t;andqi(-1)
++   and%0\t%2
++   and%0\t%2"
++   [(set_attr "length" "1,0,3,2")])
++
++
++;;--------------------------------------------------------------------
++;;- or
++;;--------------------------------------------------------------------
++
++(define_insn "iorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (ior:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "iorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q, qc")
++    (ior:QI (match_operand:QI 1 "whole_register_operand" "%0,0, 0")
++    (match_operand:QI 2 "whole_general_operand"          " O,m,i")))]
++  ""
++  "@
++   \t;iorqi(ZERO)
++   or%0\t%2
++   or%0\t%2"
++   [(set_attr "length" "0,3,2")])
++
++;;--------------------------------------------------------------------
++;;- xor
++;;--------------------------------------------------------------------
++
++(define_insn "xorhi3"
++  [(set (match_operand:HI 0 "register_operand" "=d")
++    (xor:HI (match_operand:HI 1 "register_operand" "%0")
++    (match_operand:HI 2 "general_operand" "mnU")))]
++  ""
++  "#")
++
++
++(define_insn "xorqi3"
++  [(set (match_operand:QI 0 "register_operand"           "=q,q,q,q")
++    (xor:QI (match_operand:QI 1 "whole_register_operand" "%0,0,0,0")
++    (match_operand:QI 2 "whole_general_operand"          " O,N,m,i")))]
++  ""
++  "@
++   \t;xorqi(ZERO)
++   com%0\t;xorqi(-1)
++   eor%0\t%2
++   eor%0\t%2"
++   [(set_attr "length" "0,1,3,2")])
++
++;;--------------------------------------------------------------------
++;;-  Two's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "neghi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,!a")
++    (neg:HI (match_operand:HI 1 "general_operand"   "0, 0")))]
++  ""
++  "@
++   nega\;negb\;sbca\t#0
++   exg\td,%0\;nega\;negb\;sbca\t#0\;exg\td,%0"
++  [(set_attr "length" "5,9")])
++
++
++(define_insn "negqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   neg%0
++   neg\t%0"
++  [(set_attr "length" "1,3")])
++
++
++;;--------------------------------------------------------------------
++;;-  One's Complements
++;;--------------------------------------------------------------------
++
++(define_insn "one_cmplhi2"
++  [(set (match_operand:HI 0 "nonimmediate_operand" "=d,?tm,???a")
++    (not:HI (match_operand:HI 1 "general_operand"   "0,  0,   0")))]
++  ""
++  "@
++   coma\;comb
++   com\t%0\;com\t%L0
++   exg\td,%0\;coma\;comb\;exg\td,%0"
++  [(set_attr "length" "2,6,6")])
++
++
++(define_insn "one_cmplqi2"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q,m")
++    (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
++  ""
++  "@
++   com%0
++   com\t%0"
++  [(set_attr "length" "1,3")])
++
++;;--------------------------------------------------------------------
++;;- Shifts/rotates
++;;--------------------------------------------------------------------
++
++(define_code_iterator bit_code [ashift ashiftrt lshiftrt])
++(define_code_attr bit_code_name [(ashift "ashl") (ashiftrt "ashr") (lshiftrt "lshr")])
++
++(define_mode_iterator bit_mode [QI HI])
++(define_mode_attr bit_mode_name [(QI "qi3") (HI "hi3")])
++
++;; Emit RTL for any shift (handles all 3 opcodes and 2 mode sizes)
++
++(define_expand "<bit_code:bit_code_name><bit_mode:bit_mode_name>"
++  [(set (match_operand:bit_mode 0 "nonimmediate_operand" "")
++    (bit_code:bit_mode (match_operand:bit_mode 1 "general_operand" "")
++    (match_operand:bit_mode 2 "nonmemory_operand" "")))]
++  ""
++{
++})
++
++; Individual instructions implemented in the CPU.
++
++
++(define_insn "*ashift1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashift:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asl\t%0
++   asl%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*lshiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (lshiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   lsr\t%0
++   lsr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*ashiftrt1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (ashiftrt:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   asr\t%0
++   asr%0"
++  [(set_attr "length" "3,1")])
++
++(define_insn "*rotate1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotate:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   rol\t%0
++   rol%0"
++  [(set_attr "length" "3,1")])
++
++
++(define_insn "*rotatert1"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=m,q")
++    (rotatert:QI (match_operand:QI 1 "general_operand" "0,0") (const_int 1)))]
++  ""
++  "@
++   ror\t%0
++   ror%0"
++  [(set_attr "length" "3,1")])
++
++
++; A shift by 8 for D reg can be optimized by just moving
++; between the A/B halves, and then zero/sign extending or
++; filling in zeroes.
++; Because GCC does not understand that 'A' and 'D' refer to
++; the same storage location, we must use 'USE' throughout
++; to prevent deletion of 'unnecessary' instructions.
++; Similar optimization for MEM would require a scratch register
++; so is not done here.
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_A_REGNUM) (reg:QI HARD_D_REGNUM))
++   (use (reg:QI HARD_A_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (const_int 0))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (lshiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (zero_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++(define_split
++  [(set (reg:HI HARD_D_REGNUM) (ashiftrt:HI (reg:HI HARD_D_REGNUM) (const_int 8)))]
++  "reload_completed"
++  [
++   (use (reg:HI HARD_D_REGNUM))
++   (set (reg:QI HARD_D_REGNUM) (reg:QI HARD_A_REGNUM))
++   (use (reg:QI HARD_D_REGNUM))
++   (set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   ]
++  "")
++
++
++; On the WPC hardware, there is a shift register that can be used
++; to compute (1<<n) efficiently in two instructions.  Note that this
++; form only works when using -mint8 though, because C will promote
++; to 'int' when doing this operation.  TODO : we need a 16-bit form too.
++(define_insn "ashlqi3_wpc"
++  [(set (match_operand:QI 0 "nonimmediate_operand" "=q")
++    (ashift:QI (match_operand:QI 1 "immediate_operand" "I")
++    (match_operand:QI 2 "general_operand" "q")))]
++  "TARGET_WPC"
++  "st%2\t0x3FF7\;ld%0\t0x3FF7"
++  [(set_attr "length" "6")])
++
++
++; Internal instructions for shifting by a constant.
++; Two forms are provided, one for QImode, one for HImode.
++; These are always split into the above instructions
++; (except for QImode forms that directly match one of the
++; above instructions, in which the condition will not
++; allow the splitter to match).
++
++(define_insn_and_split "<bit_code:bit_code_name>hi3_const"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=dm")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "immediate_operand"            "n")))]
++  ""
++  "#"
++  "reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++
++(define_insn_and_split "<bit_code:bit_code_name>qi3_const"
++  [(set (match_operand:QI 0 "nonimmediate_operand"     "=qm")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "immediate_operand"            "n")))]
++  "INTVAL (operands[2]) > 1"
++  "#"
++  "&& reload_completed"
++  [(const_int 0)]
++{
++  m6809_split_shift (<bit_code:CODE>, operands);
++  DONE;
++})
++
++; Internal instructions for shifting by a nonconstant.
++; These expand into complex assembly.
++
++(define_insn "<bit_code:bit_code_name>hi3_reg"
++  [(set (match_operand:HI 0 "nonimmediate_operand"     "=d")
++    (bit_code:HI (match_operand:HI 1 "general_operand" "0")
++    (match_operand:HI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "20")])
++
++
++(define_insn "<bit_code:bit_code_name>qi3_reg"
++  [(set (match_operand:QI 0 "nonimmediate_operand"    "=q")
++    (bit_code:QI (match_operand:QI 1 "general_operand" "0")
++    (match_operand:QI 2 "nonimmediate_operand"         "v")))]
++  ""
++{
++  m6809_output_shift_insn (<bit_code:CODE>, operands);
++  return "";
++}
++  [(set_attr "length" "16")])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Jumps and transfers
++;;--------------------------------------------------------------------
++
++;;; The casesi pattern is normally *not* defined; see 'tablejump' instead.
++(define_expand "casesi"
++  [(match_operand:HI 0 "register_operand" "")   ; index to jump on
++   (match_operand:HI 1 "immediate_operand" "")   ; lower bound
++   (match_operand:HI 2 "immediate_operand" "")   ; total range
++   (match_operand 3 "" "")   ; table label
++   (match_operand 4 "" "")]  ; out of range label
++  "TARGET_BYTE_INT && TARGET_CASESI"
++{
++  m6809_do_casesi (operands[0], operands[1], operands[2],
++                   operands[3], operands[4]);
++  DONE;
++})
++
++(define_insn "tablejump_short_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (zero_extend:HI (match_operand:QI 0 "register_operand" "q")))))]
++  ""
++  "jmp\t[b,x]\t;tablejump_short_offset"
++  [(set_attr "length" "3")])
++
++(define_insn "tablejump_long_offset"
++  [(set (pc)
++       (mem:HI (plus:HI (match_operand:HI 1 "register_operand" "U")
++                (match_operand:HI 0 "register_operand" "d"))))]
++  ""
++  "jmp\t[d,x]\t;tablejump_long_offset"
++  [(set_attr "length" "3")])
++
++
++ ;; A tablejump operation gives the address in operand 0, with the
++ ;; CODE_LABEL for the table in operand 1.  The 'define_expand'
++ ;; shows the arguments as GCC presents them.  For a register
++ ;; operand, the assembly code is straightforward.  For a MEM,
++ ;; assumed to be a SYMBOL_REF, two forms are given, one normal
++ ;; and one for PIC mode.
++ (define_expand "tablejump"
++    [(parallel [
++     (set (pc) (match_operand:HI 0 "" ""))
++     (use (label_ref (match_operand 1 "" "")))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++    ""
++ {
++ })
++
++
++(define_insn "*tablejump_reg"
++   [(parallel [
++      (set (pc)
++         (match_operand:HI 0 "register_operand" "a"))
++      (use (label_ref (match_operand 1 "" "")))
++      (clobber (match_scratch:HI 2 ""))
++      ])]
++   ""
++   "jmp\t,%0"
++   [(set_attr "length" "3")])
++
++
++(define_insn "*tablejump_symbol"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "a")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 ""))
++     ])]
++  "!flag_pic"
++{
++  output_asm_insn ("jmp\t[%a1,%0]", operands);
++  return "";
++}
++  [(set_attr "length" "4")])
++
++
++(define_insn "*tablejump_symbol_pic"
++  [(parallel [
++     (set (pc)
++        (mem:HI
++           (plus:HI (match_operand:HI 0 "register_operand" "d")
++                    (label_ref (match_operand 1 "" "")))))
++     (use (label_ref (match_dup 1)))
++     (clobber (match_scratch:HI 2 "=&a"))
++     ])]
++  "flag_pic"
++{
++  output_asm_insn ("lea%2\t%a1,pcr", operands);
++  output_asm_insn ("ld%0\t%0,%2", operands);
++  output_asm_insn ("jmp\t%0,%2", operands);
++  return "";
++}
++  [(set_attr "length" "8")])
++
++
++(define_insn "indirect_jump"
++  [(set (pc)
++    (match_operand:HI 0 "register_operand" "a"))]
++  ""
++  "jmp\t,%0"
++  [(set_attr "length" "3")])
++
++
++(define_insn "jump"
++  [(set (pc) (label_ref (match_operand 0 "" "")))]
++  ""
++{
++  return output_branch_insn ( LABEL_REF, operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "branch"))])
++
++; Output assembly for a condition branch instruction.
++(define_insn "*cond_branch"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++        (label_ref (match_operand 0 "" "")) (pc)))]
++  ""
++{
++  return output_branch_insn ( GET_CODE(operands[1]),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++; Similar to above, but for a condition branch instruction that
++; had its operands reversed at some point.
++(define_insn "*cond_branch_reverse"
++  [(set (pc)
++    (if_then_else
++      (match_operator 1 "comparison_operator" [(cc0) (const_int 0)])
++      (pc) (label_ref (match_operand 0 "" ""))))]
++  ""
++{
++  return output_branch_insn ( reverse_condition (GET_CODE(operands[1])),
++    operands, get_attr_length (insn));
++}
++  [(set (attr "type") (const_string "cbranch"))])
++
++
++
++;;--------------------------------------------------------------------
++;;-  Calls
++;;--------------------------------------------------------------------
++
++;; Generate a call instruction for a function that does not
++;; return a value.  The expander is used during RTL generation.
++;; The instructions below are used during matching; only one
++;; of them will be used, depending on the type of function
++;; being called.  The different conditions are:
++;;
++;;    1) far_functionp - is this a far function?  Those need
++;;    to be output as indirect calls through a far-function
++;;    handler.
++;;
++;;    2) noreturn_functionp - if the function does not return,
++;;    we can use a 'jmp' instead of a 'jsr' to call it.
++;;
++;;    3) is PIC mode enabled?  If so, we'll always use
++;;    relative calls (lbsr or lbra).
++;;
++;; Note: not all combinations are fully supported, especially
++;; relating to PIC.
++;;
++;; The 'bsr' instruction is never generated.
++
++(define_expand "call"
++  [(call (match_operand:HI 0 "memory_operand" "")
++    (match_operand:HI 1 "general_operand" ""))]
++  ""
++  "")
++
++(define_insn "*call_nopic_far"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "far_functionp (operands[0])"
++{
++  output_far_call_insn (operands, 0);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++; PIC forms come first, and should only match
++; (MEM (SYMBOL_REF)).  Other MEM forms are treated as usual.
++(define_insn "*call_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && !noreturn_functionp (operands[0])"
++  "lbsr\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "!noreturn_functionp (operands[0])"
++  "jsr\t%0"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++(define_insn "*call_noreturn_pic"
++  [(call (mem:HI (match_operand:HI 0 "symbolic_operand" ""))
++    (match_operand:HI 1 "general_operand" "g"))]
++  "flag_pic && noreturn_functionp (operands[0])"
++  "lbra\t%C0"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_noreturn_nopic"
++  [(call (match_operand:HI 0 "memory_operand" "m")
++    (match_operand:HI 1 "general_operand" "g"))]
++  "noreturn_functionp (operands[0])"
++  "jmp\t%0"
++  [(set_attr "length" "3")])
++
++
++;;
++;; Same as above, but for functions that do return a value.
++;;
++(define_expand "call_value"
++  [(set (match_operand 0 "" "")
++    (call (match_operand:HI 1 "memory_operand" "")
++    (match_operand:HI 2 "general_operand" "")))]
++  ""
++  "")
++
++
++(define_insn "*call_value_far"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  "far_functionp (operands[1])"
++{
++  output_far_call_insn (operands, 1);
++  return "";
++}
++  [(set_attr "length" "6")])
++
++
++(define_insn "*call_value_pic"
++  [(set (match_operand 0 "" "=gz")
++    (call (mem:HI (match_operand:HI 1 "symbolic_operand" ""))
++    (match_operand:HI 2 "general_operand" "g")))]
++  "flag_pic"
++  "lbsr\t%C1"
++  [(set_attr "length" "4")])
++
++
++(define_insn "*call_value_nopic"
++  [(set (match_operand 0 "" "=gz")
++    (call (match_operand:HI 1 "memory_operand" "m")
++    (match_operand:HI 2 "general_operand" "g")))]
++  ""
++  "jsr\t%1"
++  [(set_attr "length" "3")
++   (set (attr "cycles") (const_int JSR_EXTENDED_CYCLES))])
++
++
++
++;;
++;; How to generate an untyped call.
++;;
++(define_expand "untyped_call"
++  [(parallel [(call (match_operand 0 "" "")
++        (const_int 0))
++      (match_operand 1 "" "")
++      (match_operand 2 "" "")])]
++  ""
++{
++  int i;
++
++  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
++  for (i=0; i < XVECLEN (operands[2], 0); i++)
++  {
++    rtx set = XVECEXP (operands[2], 0, i);
++    emit_move_insn (SET_DEST (set), SET_SRC (set));
++  }
++  emit_insn (gen_blockage ());
++  DONE;
++})
++
++
++(define_expand "sibcall"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "")
++            (match_operand:HI 1 "immediate_operand" ""))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_1"
++  [(parallel
++     [(call (match_operand:HI 0 "memory_operand" "m")
++            (match_operand:HI 1 "immediate_operand" "i"))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%0"
++  [(set_attr "length" "4")])
++
++
++(define_expand "sibcall_value"
++  [(parallel
++     [(set (match_operand 0 "" "")
++         (call (match_operand:HI 1 "memory_operand" "")
++               (match_operand:HI 2 "immediate_operand" "")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  ""
++  "")
++
++(define_insn "*sibcall_value_1"
++  [(parallel
++     [(set (match_operand 0 "" "=gz")
++         (call (match_operand:HI 1 "memory_operand" "m")
++               (match_operand:HI 2 "immediate_operand" "i")))
++      (use (reg:HI HARD_PC_REGNUM))])]
++  "SIBLING_CALL_P(insn)"
++  "jmp\t%1"
++  [(set_attr "length" "4")])
++
++
++;;--------------------------------------------------------------------
++;;-  Function Entry and Exit
++;;--------------------------------------------------------------------
++
++;; On entry to a function, the stack frame looks as follows:
++;; - return address (pushed by the caller)
++;; - saved registers
++;; - local variable storage
++;;
++;; If the function does not modify the stack after that, then
++;; any of these can be accessed directly as an offset from
++;; STACK_POINTER_REGNUM.  Otherwise, a frame pointer is required.
++;; In that case, the prologue must also initialize HARD_FRAME_POINTER_REGNUM
++;; and all references to the stack frame will use that as a base instead.
++;;
++(define_expand "prologue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_prologue_insns ();
++  DONE;
++})
++
++
++;; The function epilogue does exactly the reverse of the prologue,
++;; deallocating local variable space, restoring saved registers,
++;; and returning.
++;;
++;; For the 6809, the return may be 'rti' if the function was
++;; declared as an interrupt function, but is normally 'rts'.
++;;
++;; Also, as an optimization, the register restore and the 'rts'
++;; can be combined into a single instruction, by adding 'PC' to the
++;; list of registers to be restored.  This is only done if there are
++;; any saved registers, as 'rts' is more efficient by itself.
++;;
++(define_expand "epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (false);
++  DONE;
++})
++
++
++(define_expand "sibcall_epilogue"
++  [(const_int 0)]
++  "prologue_epilogue_required ()"
++{
++  emit_epilogue_insns (true);
++  DONE;
++})
++
++
++;; The RTS instruction
++(define_insn "return_rts"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () == 0"
++  "rts"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++(define_insn "return_puls_pc"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "!m6809_current_function_has_type_attr_p (\"interrupt\")
++   && m6809_get_live_regs () != 0"
++  ""
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTS_CYCLES))])
++
++;; The RTI instruction
++(define_insn "return_rti"
++  [(return)
++   (use (reg:HI HARD_PC_REGNUM))]
++  "m6809_current_function_has_type_attr_p (\"interrupt\")"
++  "rti"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int RTI_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;-  Unspecified instructions
++;;--------------------------------------------------------------------
++
++;; An instruction that has the effect of an unspec_volatile, but
++;; which doesn't require emitting any assembly code.
++(define_insn "blockage"
++  [(unspec_volatile [(const_int 0)] UNSPEC_BLOCKAGE)]
++  ""
++  ""
++  [(set_attr "length" "0")
++   (set (attr "cycles") (const_int 0))])
++
++
++;; Say how to push multiple registers onto the stack, using
++;; the 6809 'pshs' instruction.  The operand is a regset
++;; specifying which registers to push.
++;;
++;; The operand mode is not given intentionally, so as to allow
++;; any possible integer mode for the regset.
++;;
++;; See below for a peephole that can combine consecutive push
++;; instructions that qualify for merging.
++(define_insn "register_push"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "pshs\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++;; Say how to pop multiple registers from the stack, using
++;; the 6809 'puls' instruction.  The operand is the register
++;; bitset value.
++(define_insn "register_pop"
++  [(use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile
++      [(match_operand 0 "immediate_operand" "")] UNSPEC_POP_RS)
++    (clobber (reg:HI HARD_S_REGNUM))]
++  ""
++  "puls\t%R0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int PSH_PUL_CYCLES))])
++
++
++(define_insn "m6809_swi"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "I,n")] UNSPEC_SWI)]
++  ""
++  "@
++   swi
++   swi%c0"
++  [(set_attr "length" "1,2")
++   (set (attr "cycles") (const_int SWI_CYCLES))])
++
++
++;; Generate the CWAI instruction
++(define_insn "m6809_cwai"
++  [(unspec_volatile
++    [(match_operand:QI 0 "immediate_operand" "")] UNSPEC_CWAI)]
++  ""
++  "cwai\t%0"
++  [(set_attr "length" "2")
++   (set (attr "cycles") (const_int CWAI_CYCLES))])
++
++
++;; Generate the SYNC instruction
++(define_insn "m6809_sync"
++  [(unspec_volatile [(const_int 0)] UNSPEC_SYNC)]
++  ""
++  "sync"
++  [(set_attr "length" "1")
++   (set (attr "cycles") (const_int SYNC_CYCLES))])
++
++
++;; Generate the NOP instruction
++(define_insn "nop"
++  [(const_int 0)]
++  ""
++  "nop"
++   [(set_attr "length" "1")
++   (set (attr "cycles") (const_int NOP_CYCLES))])
++
++
++;;--------------------------------------------------------------------
++;;- Peepholes
++;;--------------------------------------------------------------------
++
++;;; Each peephole has an ID that is used for debugging.
++;;; Each peephole condition is bracketed by calls to
++;;; m6809_match_peephole2() also for debugging.
++(define_constants [
++  (PEEP_END 0)
++  (PEEP_COND 1)
++
++  (PEEP_STACK_STORE_INC 0)
++  (PEEP_STACK_CLEAR_INC 1)
++  (PEEP_LSRB_ADCB 2)
++  (PEEP_ABX 3)
++  (PEEP_ABX2 4)
++  (PEEP_INDEXED_INC 5)
++  (PEEP_MEM_DEC 6)
++  (PEEP_MEM_INC 7)
++  (PEEP_MEM_DEC_CMP 8)
++  (PEEP_PUSH2 9)
++  (PEEP_STORE_IMPLIES_CC 10)
++  (PEEP_DEC_IMPLIES_CC 11)
++  (PEEP_LEAB 12)
++  (PEEP_LDX_INDIRECT 13)
++  (PEEP_POP_JUNK 14)
++])
++
++
++;;; Optimize 'leas -1,s' followed by 'stb ,s'.  This can happen if the
++;;; function prologue needs to allocate stack space and 'b' is placed
++;;; into that local right away.  Combine the stack allocation with the
++;;; store using preincrement mode.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM)
++        (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM))
++        (match_operand:QI 0 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_STACK_STORE_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (match_dup 0))]
++  "")
++
++
++;;; Same as above, but for a 'clr ,s' that follows the prologue.
++(define_peephole2
++  [(set (reg:HI HARD_S_REGNUM) (plus:HI (reg:HI HARD_S_REGNUM) (const_int -1)))
++   (set (mem:QI (reg:HI HARD_S_REGNUM)) (const_int 0))]
++  "m6809_match_peephole2 (PEEP_STACK_CLEAR_INC, PEEP_END)"
++  [(set (mem:QI (pre_dec:HI (reg:HI HARD_S_REGNUM))) (const_int 0))]
++  "")
++
++
++;;; Merge two consecutive push instructions into a single register_push.
++(define_peephole2
++  [(set (match_operand 0 "push_operand" "")
++    (match_operand 1 "register_operand" ""))
++   (set (match_operand 2 "push_operand" "")
++    (match_operand 3 "register_operand" ""))]
++  "m6809_match_peephole2 (PEEP_PUSH2, PEEP_COND)
++   && reload_completed
++   && GET_MODE (operands[1]) == GET_MODE (operands[3])
++   && m6809_can_merge_pushpop_p (UNSPEC_PUSH_RS, 1 << REGNO (operands[1]), 1 << REGNO (operands[3]))
++   && m6809_match_peephole2 (PEEP_PUSH2, PEEP_END)"
++  [(parallel [
++    (use (reg:HI HARD_S_REGNUM))
++    (unspec_volatile [(match_dup 4)] UNSPEC_PUSH_RS)
++    (clobber (reg:HI HARD_S_REGNUM))])
++   (use (match_dup 1))
++   (use (match_dup 3))]
++{
++  operands[4] = gen_rtx_CONST_INT (QImode,
++    (1 << REGNO (operands[1])) | (1 << REGNO (operands[3])));
++})
++
++
++;;; Convert 'stX ,--s' into a push instruction.  Use the regset
++;;; notation, so that it may be combined with an adjacent regset.
++;;; TBD - this doesn't compile some code cleanly.
++;(define_peephole2
++;  [(set (mem:HI (pre_dec:HI (reg:HI HARD_S_REGNUM)))
++;        (reg:HI HARD_X_REGNUM))]
++;  "reload_completed"
++;  [(parallel [
++;    (use (reg:HI HARD_S_REGNUM))
++;    (unspec_volatile [(match_dup 0)] UNSPEC_PUSH_RS)
++;    (clobber (reg:HI HARD_S_REGNUM))])]
++;{
++;  operands[0] = gen_rtx_CONST_INT (HImode, X_REGBIT);
++;})
++
++
++;;;
++;;; q = (q+1)/2 can be optimized as "lsrb; adcb".  This also
++;;; won't overflow when q=0xFF.
++;;; TODO : this form isn't accounting for promotion when
++;;; using 16-bit ints.
++;;;
++(define_peephole
++  [(set (reg:QI HARD_D_REGNUM)
++    (lshiftrt:QI (plus:HI (match_dup 0) (const_int 1)) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_LSRB_ADCB, PEEP_END)"
++  "lsrb\;adcb\t#0; peephole"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Optimize the case of following a register store with a test
++;; of reg or mem just moved.
++;;
++(define_peephole
++  [(set (match_operand:HI 0 "memory_operand" "=m")
++  (match_operand:HI 1 "register_operand" "r"))
++   (set (cc0) (match_operand:HI 2 "general_operand" "g"))]
++  "m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_COND)
++   && (operands[2] == operands[0] || operands[2] == operands[1])
++   && m6809_match_peephole2 (PEEP_STORE_IMPLIES_CC, PEEP_END)"
++  "st%1\t%0\t;movhi: R:%1 -> %0 w/ implied test of %2"
++  [(set_attr "length" "4")])
++
++
++;; Optimize a pair of SET instructions in which the second insn
++;; is the reverse of the first one.  I.e.
++;;
++;; A = B
++;;        ---->  A = B
++;; B = A
++;;
++;; The second insn is redundant.  Define two patterns, one for QI, one for HI.
++;; But don't do this if either is a VOLATILE MEM.
++(define_peephole2
++  [(set (match_operand:HI 0 "nonimmediate_operand" "")
++        (match_operand:HI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++  (set (match_dup 1) (match_dup 0))]
++  "!MEM_P (operands[0]) || !MEM_P (operands[1]) || (!MEM_VOLATILE_P (operands[0]) && !MEM_VOLATILE_P (operands[1]))"
++  [(set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;
++;; Optimize the sum of an 8-bit and 16-bit using the 'abx' instruction
++;; if B and X can be used.  Two patterns are provided to catch both
++;; X=X+D and X=D+X.
++;;
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX, PEEP_END)"
++  "abx"
++  [(set_attr "length" "1")])
++
++;;; Likewise, handle when B is scaled by 2 prior to the add.
++;;; Instead of shifting B in 4 cycles, just do the ABX a second
++;;; time, in only 3 cycles.
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_D_REGNUM) (reg:HI HARD_X_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++(define_peephole
++  [(set (reg:HI HARD_D_REGNUM)
++    (zero_extend:HI (match_operand:QI 0 "general_operand" "q")))
++   (set (reg:HI HARD_D_REGNUM)
++    (ashift:HI (reg:HI HARD_D_REGNUM) (const_int 1)))
++   (set (reg:HI HARD_X_REGNUM)
++    (plus:HI (reg:HI HARD_X_REGNUM) (reg:HI HARD_D_REGNUM)))]
++  "m6809_match_peephole2 (PEEP_ABX2, PEEP_END)"
++  "abx\;abx"
++  [(set_attr "length" "2")])
++
++
++;;
++;; Work around a compiler bug that generates bad code when copying
++;; between 32-bit memory addresses after a libcall.  The problem seen is
++;; that the source is MEM (REG X), but X is used as the reload register.
++;; The second half of the copy therefore fails.
++;;
++;; The solution is to switch the reload register to D, since that is guaranteed
++;; not to be in use right after a libcall.
++;;
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_operand:HI 0 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_operand:HI 1 "nonimmediate_operand" "") (reg:HI HARD_X_REGNUM))]
++  "reload_completed"
++  [(set (reg:HI HARD_D_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))
++   (set (match_dup 0) (reg:HI HARD_D_REGNUM))
++   (set (reg:HI HARD_X_REGNUM)
++      (mem:HI (plus:HI (reg:HI HARD_X_REGNUM) (const_int 2))))
++   (set (match_dup 1) (reg:HI HARD_X_REGNUM))]
++  "")
++
++
++;; Turn "and then test" into a "bit test" operation.
++;; Provide variants for immediate and memory sources
++;; This is the most used peephople.
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "immediate_operand" "i")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "3")])
++; 
++; (define_peephole
++;   [(set (match_operand:QI 0 "register_operand" "=q")
++;     (and:QI (match_operand:QI 1 "register_operand" "0")
++;       (match_operand:QI 2 "memory_operand" "m")))
++;    (set (cc0) (match_dup 0))]
++;   ""
++;   "bit%0\t%2"
++;   [(set_attr "length" "4")])
++
++
++;; Turn a "decrement, then test" sequence into just a "decrement".
++;; The test can be omitted, since it is implicitly done.
++(define_peephole2
++  [(set (match_operand:QI 0 "nonimmediate_operand" "")
++    (plus:QI (match_operand:QI 1 "whole_general_operand" "")
++    (match_operand:QI 2 "immediate_operand" "")))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_DEC_IMPLIES_CC, PEEP_END)"
++  [(set (match_dup 0) (plus:QI (match_dup 1) (match_dup 2)))]
++  "")
++
++
++;; Merge an indexed register increment with a previous usage.
++;; This is usually done automatically, but not always
++;; The 'use' should be optional; in all cases where this has been
++;; seen, it is required though.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++     (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (use (match_dup 0))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "m6809_match_peephole2 (PEEP_INDEXED_INC, PEEP_END)"
++  [(set (match_dup 0) (mem:QI (post_inc:HI (match_dup 1))))
++   (use (match_dup 0))]
++  "")
++
++
++;;; Merge "ldX MEM; ldX ,X" into a single instruction using
++;;; the indirect mode.
++(define_peephole2
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (match_operand:HI 0 "general_operand" "")))
++   (set (reg:HI HARD_X_REGNUM) (mem:HI (reg:HI HARD_X_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LDX_INDIRECT, PEEP_END)"
++  [(set (reg:HI HARD_X_REGNUM)
++    (mem:HI (mem:HI (match_dup 0))))]
++  "")
++
++
++;;; Reorder a store followed by a unary operation on that memory
++;;; so that the unary is performed and then the store.  Consider
++;;; a binary shift operation, which will be decomposed into
++;;; identical single shifts, also.
++;;; TODO - recognize more than just 'ashift' here.
++(define_peephole2
++  [(set (match_operand:QI 0 "memory_operand" "")
++        (match_operand:QI 1 "register_operand" ""))
++   (set (match_dup 0)
++        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++  "reload_completed"
++  [(set (match_dup 1)
++        (ashift:QI (match_dup 1) (match_operand:QI 2 "immediate_operand")))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++;;; Likewise, reorder a unary MEM followed by a load, so that the load
++;;; is done first, then use the REG instead of the MEM.
++;;;(define_peephole2
++;;;  [(set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))
++;;;   (set (match_operand:QI 0 "register_operand" "")
++;;;        (match_operand:QI 1 "memory_operand" ""))]
++;;;  "reload_completed"
++;;;  [(set (match_dup 0) (match_dup 1))
++;;;   (set (match_dup 0)
++;;;        (ashift:QI (match_dup 0) (match_operand:QI 2 "immediate_operand")))]
++;;;  "")
++
++
++;;; Replace sex; leaX d,Y with leaX b,Y.
++;;;
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (match_operand:HI 1 "index_register_operand" "")
++                 (reg:HI HARD_D_REGNUM)))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++(define_peephole2
++  [(set (reg:HI HARD_D_REGNUM) (sign_extend:HI (reg:QI HARD_D_REGNUM)))
++   (set (match_operand:HI 0 "index_register_operand" "")
++        (plus:HI (reg:HI HARD_D_REGNUM)
++          (match_operand:HI 1 "index_register_operand" "")))]
++  "reload_completed && m6809_match_peephole2 (PEEP_LEAB, PEEP_END)"
++  [(set (match_dup 0)
++        (plus:HI (match_dup 1) (reg:QI HARD_D_REGNUM)))]
++  "")
++
++
++;;; Replace ldb; decb; stb; tstb with dec(mem).  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))
++   (set (cc0) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC_CMP, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace ldb; decb; stb with dec(mem); ldb.  If the
++;;; register is not needed, then the load will get deleted
++;;; automatically, but it may be needed for comparisons.
++;;; Same for incb/inc.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_DEC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int -1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (match_operand:QI 1 "nonimmediate_operand" ""))
++   (set (match_dup 0) (plus:QI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++  "m6809_match_peephole2 (PEEP_MEM_INC, PEEP_END)"
++  [(set (match_dup 1) (plus:QI (match_dup 1) (const_int 1)))
++   (set (match_dup 0) (match_dup 1))]
++  "")
++
++
++;;; Replace "andb #N; cmpb #N; bhi" with "andb #N", if it can be proven
++;;; that the branch can never occur because of the limited range of B.
++;;; N must be a power of two for this to make sense.  This helps with
++;;; the default cases of switch statements on a value (x & N).
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++    (and:QI (match_dup 0) (match_operand:QI 1 "immediate_operand" "")))
++   (set (cc0)
++    (compare (match_dup 0) (match_dup 1)))
++   (set (pc) (if_then_else (gtu (cc0) (const_int 0)) (match_operand 2 "" "") (match_operand 3 "" "")))
++   ]
++  "reload_completed && power_of_two_p (INTVAL (operands[1]) + 1)"
++  [(set (match_dup 0) (and:QI (match_dup 0) (match_dup 1)))]
++  "")
++
++;;; Replace ldd <mem>; addd #1; std <mem> with 16-bit increment
++;;; of the mem, but only if D is dead.  Same for 16-bit decrement.
++;;; <mem> must be offsettable for the instruction to match.
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int 1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++  "")
++
++(define_peephole2
++  [(set (match_operand:HI 0 "register_operand" "") (match_operand:HI 1 "memory_operand" ""))
++   (set (match_dup 0) (plus:HI (match_dup 0) (const_int -1)))
++   (set (match_dup 1) (match_dup 0))]
++   "reload_completed
++    && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
++    && peep2_reg_dead_p (3, operands[0])"
++  [(set (match_dup 1) (plus:HI (match_dup 1) (const_int -1)))]
++  "")
++
++
++;;; Replace a load or store using an indexed register, followed by an increment of that
++;;; register, with the combined form using autoincrement.
++(define_peephole2
++  [(set (match_operand:QI 0 "register_operand" "")
++        (mem:QI (match_operand:HI 1 "index_register_operand" "")))
++   (set (match_dup 1) (plus:HI (match_dup 1) (const_int 1)))]
++   "reload_completed"
++  [(set (match_dup 0) (mem:QI (post_inc (match_dup 1))))]
++  "")
++
++
++;;- mode:emacs-lisp
++;;- comment-start: ";;- "
++;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
++;;- eval: (modify-syntax-entry ?[ "(]")
++;;- eval: (modify-syntax-entry ?] ")[")
++;;- eval: (modify-syntax-entry ?{ "(}")
++;;- eval: (modify-syntax-entry ?} "){")
++;-; vim: set ts=2:
++;-; vim: set expandtab:
++;-; vim: set filetype=lisp:
++;;- End:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809.opt gcc-4.6.4/gcc/config/m6809/m6809.opt
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809.opt	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809.opt	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,98 @@
++; Options for the M6809 port of the compiler
++;
++; Copyright (C) 2005 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, 51 Franklin Street, Fifth Floor, Boston, MA
++; 02110-1301, USA.
++
++margcount
++Target Mask(ARGCOUNT)
++Push argument count
++
++mint8
++Target RejectNegative Mask(BYTE_INT)
++Use 8-bit integers
++
++mint16
++Target RejectNegative
++Use 16-bit integers InverseMask(BYTE_INT)
++
++mreg-args
++Target Mask(REG_ARGS)
++Use registers for function arguments
++
++mshort_size 
++Target RejectNegative Mask(SMALL_SIZE_T)
++Use 8-bit size_t
++
++mlong_size
++Target RejectNegative InverseMask(SMALL_SIZE_T)
++Use 16-bit size_t
++
++mdirect
++Target Mask(DIRECT)
++Enable direct addressing
++
++mwpc
++Target RejectNegative Mask(WPC)
++Enable WPC platform extensions
++
++mexperiment
++Target RejectNegative Mask(EXPERIMENT)
++Enable current experimental feature
++
++m6309
++Target RejectNegative Mask(6309)
++Enable Hitachi 6309 extensions
++
++mcasesi
++Target RejectNegative Mask(CASESI)
++Enable the casesi pattern
++
++mfar-code-page=
++Target RejectNegative Joined Var(far_code_page_option)
++Sets the far code page value for this compilation unit
++
++mcode-section=
++Target RejectNegative Joined Var(code_section_ptr)
++Sets the name of the section for code
++
++mdata-section=
++Target RejectNegative Joined Var(data_section_ptr)
++Sets the name of the section for initialized data
++
++mbss-section=
++Target RejectNegative Joined Var(bss_section_ptr)
++Sets the name of the section for uninitialized data
++
++mabi_version=
++Target RejectNegative Joined Var(m6809_abi_version_ptr)
++Sets the calling convention
++
++msoft-reg-count=
++Target RejectNegative Joined Var(m6809_soft_reg_count)
++Sets the number of soft registers that can be used
++
++mdret
++Target RejectNegative Mask(DRET)
++Put function call results in D, not X
++
++mfar-stack-param
++Target Mask(FAR_STACK_PARAM)
++Enable stack parameters to a farcall
++
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h gcc-4.6.4/gcc/config/m6809/m6809-protos.h
+--- gcc-4.6.4-clean/gcc/config/m6809/m6809-protos.h	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/m6809-protos.h	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,94 @@
++/* GCC for 6809 : machine-specific function prototypes
++
++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 __M6809_PROTOS_H__
++#define __M6809_PROTOS_H__
++
++void 					print_options (FILE *file);
++void 					m6809_cpu_cpp_builtins (void);
++void 					m6809_override_options (void);
++void 					m6809_init_builtins (void);
++unsigned int 		m6809_get_live_regs (void);
++const char * 		m6809_get_regs_printable (unsigned int regs);
++unsigned int 		m6809_get_regs_size (unsigned int regs);
++int 					m6809_function_has_type_attr_p (tree decl, const char *);
++int 					m6809_current_function_has_type_attr_p (const char *);
++int 					prologue_epilogue_required (void);
++int 					noreturn_functionp (rtx x);
++void 					output_function_prologue (FILE *file, int size);
++void 					output_function_epilogue (FILE *file, int size);
++int 					check_float_value (enum machine_mode mode, double *d, int overflow);
++void 					m6809_asm_named_section (const char *name, unsigned int flags, tree decl);
++void 					m6809_asm_file_start (void);
++void              m6809_output_ascii (FILE *fp, const char *str, unsigned long size);
++void              m6809_declare_function_name (FILE *asm_out_file, const char *name, tree decl);
++void              m6809_reorg (void);
++int               m6809_current_function_is_void (void);
++int               m6809_can_merge_pushpop_p (int op, int regs1, int regs2);
++int               m6809_function_value_regno_p (unsigned int regno);
++void              emit_prologue_insns (void);
++void              emit_epilogue_insns (bool);
++void              m6809_conditional_register_usage (void);
++void              m6809_output_quoted_string (FILE *asm_file, const char *string);
++int               m6809_match_peephole2 (unsigned int peephole_id, unsigned int stage);
++int               m6809_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode);
++int               power_of_two_p (unsigned int n);
++void              m6809_do_casesi (rtx index, rtx lower_bound, rtx range, rtx table_label, rtx default_label);
++void              m6809_output_addsi3 (int rtx_code, rtx *operands);
++rtx               m6809_function_arg_on_stack (CUMULATIVE_ARGS *cump);
++void              expand_constant_shift (int code, rtx dst, rtx src, rtx count);
++int               m6809_single_operand_operator (rtx exp);
++
++#ifdef TREE_CODE
++int m6809_init_cumulative_args (CUMULATIVE_ARGS cum, tree fntype, rtx libname);
++#endif /* TREE_CODE */
++
++#ifdef RTX_CODE
++void 					print_direct_prefix (FILE *file, rtx addr);
++void 					print_operand (FILE *file, rtx x, int code);
++void 					print_operand_address (FILE *file, rtx addr);
++void 					notice_update_cc (rtx exp, rtx insn);
++enum 					reg_class m6809_preferred_reload_class (rtx x, enum reg_class regclass);
++rtx 					gen_rtx_const_high (rtx r);
++rtx 					gen_rtx_const_low (rtx r);
++rtx 					gen_rtx_register_pushpop (int pop_flag, int regs);
++void 					emit_libcall_insns (enum machine_mode mode, const char *name, rtx *operands, int count);
++const char *		output_branch_insn (enum rtx_code code, rtx *operands, int length);
++void 					output_far_call_insn (rtx *operands, int has_return);
++void 					m6809_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt);
++rtx 					m6809_expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode, int ignore);
++const char *      far_functionp (rtx x);
++rtx               m6809_function_value (const tree valtype, const tree func);
++void              m6809_output_shift_insn (int rtx_code, rtx *operands);
++
++const char * m6809_get_decl_bank (tree decl);
++void output_branch_insn1 (const char *opcode, rtx *operands, int long_p);
++rtx m6809_builtin_operand (tree arglist, enum machine_mode mode, int opnum);
++const char * far_function_type_p (tree type);
++void m6809_asm_trampoline_template(FILE *f);
++bool m6809_frame_pointer_required (void);
++int m6809_can_eliminate (int from, int to);
++int m6809_initial_elimination_offset (int from, int to);
++void m6809_emit_move_insn (rtx dst, rtx src);
++void m6809_split_shift (enum rtx_code code, rtx *operands);
++bool m6809_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED);
++
++
++#endif /* RTX_CODE */
++
++#endif /* __M6809_PROTOS_H__ */
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/predicates.md gcc-4.6.4/gcc/config/m6809/predicates.md
+--- gcc-4.6.4-clean/gcc/config/m6809/predicates.md	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/predicates.md	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,78 @@
++;; Predicate definitions for Motorola 6809
++;; Copyright (C) 2006, 2007, 2008, 2009 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 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/>.
++
++;; whole_register_operand is like register_operand, but it
++;; does not allow SUBREGs.
++(define_predicate "whole_register_operand"
++  (and (match_code "reg")
++       (match_operand 0 "register_operand")))
++
++
++;; A predicate that matches any index register.  This can be used in nameless
++;; patterns and peepholes which need a 16-bit reg, but not D.
++(define_predicate "index_register_operand"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM || REGNO (op) == HARD_Y_REGNUM || REGNO (op) == HARD_U_REGNUM")))
++
++
++;; match only X
++(define_predicate "register_operand_x"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_X_REGNUM")))
++
++;; match only D
++(define_predicate "register_operand_d"
++  (and (match_code "reg")
++       (match_test "REGNO (op) == HARD_D_REGNUM")))
++
++
++;; Likwise, a replacement for general_operand which excludes
++;; SUBREGs.
++(define_predicate "whole_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")))
++
++
++(define_predicate "add_general_operand"
++  (and (match_code "const_int,const_double,const,symbol_ref,label_ref,reg,mem")
++       (match_operand 0 "general_operand")
++		 (match_test "REGNO (op) != SOFT_AP_REGNUM")))
++
++
++(define_predicate "shift_count_operand"
++  (and (match_code "const_int")
++     (and (match_operand 0 "const_int_operand")
++       (match_test "INTVAL (op) == 1 || INTVAL (op) == 8"))))
++
++
++;; A predicate that matches any bitwise logical operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "logical_bit_operator"
++	(ior (match_code "and") (match_code "ior") (match_code "xor")))
++
++
++;; A predicate that matches any shift or rotate operator.  This
++;; allows for a single RTL pattern to be used for multiple operations.
++(define_predicate "shift_rotate_operator"
++	(ior (match_code "ashift") (match_code "ashiftrt") (match_code "lshiftrt")
++	     (match_code "rotate") (match_code "rotatert")))
++
++
++(define_predicate "symbolic_operand" (match_code "symbol_ref"))
++
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-coco gcc-4.6.4/gcc/config/m6809/t-coco
+--- gcc-4.6.4-clean/gcc/config/m6809/t-coco	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-coco	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,6 @@
++# For a few minor differences in code generation on the CoCo...
++T_CFLAGS = -DTARGET_COCO
++
++# For doing the startup differently on the CoCo...
++CRT0STUFF_T_CFLAGS += -DTARGET_COCO
++# vim: set filetype=make:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-m6809 gcc-4.6.4/gcc/config/m6809/t-m6809
+--- gcc-4.6.4-clean/gcc/config/m6809/t-m6809	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-m6809	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1,64 @@
++
++# ranlib doesn't exist, so define it to 'true' to make it a no-op
++RANLIB_FOR_TARGET = true
++
++# Stubs for libgcc defined by m6809 are here
++LIB1ASMSRC = m6809/libgcc1.s
++
++# Here are the functions that are implemented within libgcc1.s
++LIB1ASMFUNCS = _mulhi3 _divhi3 _modhi3 _udivhi3 _umodhi3 \
++	_euclid _seuclid _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _softregs \
++	_ashlhi3 _ashrhi3 _lshrhi3
++
++# Flags to use when building libgcc.  IN_GCC does not seem necessary,
++# although the compile breaks without it.  -DDF=SF is required to set
++# the size of "double" to the same as the size of a "float".
++TARGET_LIBGCC2_CFLAGS =-DIN_GCC -Dinhibit_libc -DDF=SF -DLIBGCC2_HAS_SF_MODE=0 -DLIBGCC2_HAS_DF_MODE=0
++
++LIB2ADDEH =
++LIB2ADDEHSTATIC =
++LIB2ADDEHSHARED =
++
++LIBGCC2_DEBUG_CFLAGS =
++LIBGCC2_CFLAGS = -Os $(LIBGCC2_INCLUDES) $(TARGET_LIBGCC2_CFLAGS) $(LIBGCC2_DEBUG_CFLAGS) $(GTHREAD_FLAGS) -DIN_LIBGCC2
++
++# Multilib information
++# This creates multiple versions of libgcc.a for each set of incompatible
++# -mxxx options.
++MULTILIB_OPTIONS  = fpic mdret
++MULTILIB_DIRNAMES =
++MULTILIB_MATCHES  =
++MULTILIB_EXCEPTIONS =
++EXTRA_MULTILIB_PARTS = crt0.o
++
++LIBGCC = stmp-multilib
++INSTALL_LIBGCC = install-multilib
++
++# We want fine grained libraries, so use the new code to build the
++# floating point emulation libraries.
++FPBIT = fp-bit.c
++
++fp-bit.c: $(srcdir)/config/fp-bit.c
++	echo '#define FLOAT' > fp-bit.c
++	echo '#define FLOAT_ONLY' >> fp-bit.c
++	echo '#define CMPtype HItype' >> fp-bit.c
++	echo '#define SMALL_MACHINE' >> fp-bit.c
++	echo '#ifdef __LITTLE_ENDIAN__' >> fp-bit.c
++	echo '#define FLOAT_BIT_ORDER_MISMATCH' >>fp-bit.c
++	echo '#endif' 		>> fp-bit.c
++	echo '#define DI SI'	>> fp-bit.c
++	cat $(srcdir)/config/fp-bit.c >> fp-bit.c
++
++# crt0.o is built from the following source file
++CRT0_S = $(srcdir)/config/m6809/crt0.S
++MCRT0_S = $(srcdir)/config/m6809/crt0.S
++
++# Flags to use when building crt0.o
++CRT0STUFF_T_CFLAGS += -fno-builtin -nostartfiles -nostdlib
++
++# Assemble startup files.
++$(T)crt0.o: $(CRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)crt0.o -x assembler-with-cpp $(CRT0_S)
++
++$(T)mcrt0.o: $(MCRT0_S) $(GCC_PASSES)
++	$(GCC_FOR_TARGET) $(CRT0STUFF_T_CFLAGS) $(MULTILIB_CFLAGS) -c -o $(T)mcrt0.o -x assembler-with-cpp $(MCRT0_S)
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-proto gcc-4.6.4/gcc/config/m6809/t-proto
+--- gcc-4.6.4-clean/gcc/config/m6809/t-proto	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-proto	2017-11-29 17:11:09.221248469 -0700
+@@ -0,0 +1,6 @@
++# For a few minor differences in code generation on a custom prototype.
++T_CFLAGS = -DTARGET_PROTO
++
++# For doing the startup differently on a custom prototype.
++CRT0STUFF_T_CFLAGS += -DTARGET_PROTO
++# vim: set filetype=make:
+diff -urN gcc-4.6.4-clean/gcc/config/m6809/t-sim gcc-4.6.4/gcc/config/m6809/t-sim
+--- gcc-4.6.4-clean/gcc/config/m6809/t-sim	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/gcc/config/m6809/t-sim	2017-11-28 21:12:11.156911596 -0700
+@@ -0,0 +1 @@
++CRT0STUFF_T_CFLAGS += -DTARGET_SIM
+diff -urN gcc-4.6.4-clean/gcc/config.gcc gcc-4.6.4/gcc/config.gcc
+--- gcc-4.6.4-clean/gcc/config.gcc	2013-03-06 10:40:07.000000000 -0700
++++ gcc-4.6.4/gcc/config.gcc	2017-11-29 17:11:09.229248437 -0700
+@@ -375,6 +375,9 @@
+         cpu_type=m32r
+ 	extra_options="${extra_options} g.opt"
+         ;;
++m6809-*-*)
++        cpu_type=m6809
++        ;;
+ m68k-*-*)
+ 	extra_headers=math-68881.h
+ 	;;
+@@ -1706,6 +1709,15 @@
+ 		thread_file='posix'
+ 	fi
+ 	;;
++m6809-coco-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-coco"
++	;;
++m6809-proto-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-proto"
++	;;
++m6809-*-*)
++	tmake_file="${tmake_file} m6809/t-m6809 m6809/t-sim"
++	;;
+ # m68hc11 and m68hc12 share the same machine description.
+ m68hc11-*-*|m6811-*-*)
+ 	tm_file="dbxelf.h elfos.h usegas.h newlib-stdint.h m68hc11/m68hc11.h"
+diff -urN gcc-4.6.4-clean/gcc/gcse.c gcc-4.6.4/gcc/gcse.c
+--- gcc-4.6.4-clean/gcc/gcse.c	2011-02-02 23:04:04.000000000 -0700
++++ gcc-4.6.4/gcc/gcse.c	2017-11-28 21:12:11.156911596 -0700
+@@ -833,7 +833,6 @@
+ 	      max_distance = (GCSE_COST_DISTANCE_RATIO * cost) / 10;
+ 	      if (max_distance == 0)
+ 		return 0;
+-
+ 	      gcc_assert (max_distance > 0);
+ 	    }
+ 	  else
+diff -urN gcc-4.6.4-clean/gcc/libgcc2.c gcc-4.6.4/gcc/libgcc2.c
+--- gcc-4.6.4-clean/gcc/libgcc2.c	2011-01-03 13:52:22.000000000 -0700
++++ gcc-4.6.4/gcc/libgcc2.c	2017-11-28 21:12:11.156911596 -0700
+@@ -485,6 +485,7 @@
+ #endif
+ 
+ #ifdef L_bswapsi2
++#if MIN_UNITS_PER_WORD > 1
+ SItype
+ __bswapsi2 (SItype u)
+ {
+@@ -494,7 +495,9 @@
+ 	  | (((u) & 0x000000ff) << 24));
+ }
+ #endif
++#endif
+ #ifdef L_bswapdi2
++#if LONG_LONG_TYPE_SIZE > 32
+ DItype
+ __bswapdi2 (DItype u)
+ {
+@@ -508,6 +511,7 @@
+ 	  | (((u) & 0x00000000000000ffull) << 56));
+ }
+ #endif
++#endif
+ #ifdef L_ffssi2
+ #undef int
+ int
+@@ -1280,7 +1284,7 @@
+ UDWtype
+ __fixunssfDI (SFtype a)
+ {
+-#if LIBGCC2_HAS_DF_MODE
++#if LIBGCC2_HAS_DF_MODE || (FLT_MANT_DIG >= W_TYPE_SIZE)
+   /* Convert the SFtype to a DFtype, because that is surely not going
+      to lose any bits.  Some day someone else can write a faster version
+      that avoids converting to DFtype, and verify it really works right.  */
+@@ -1298,7 +1302,7 @@
+ 
+   /* Assemble result from the two parts.  */
+   return ((UDWtype) hi << W_TYPE_SIZE) | lo;
+-#elif FLT_MANT_DIG < W_TYPE_SIZE
++#else
+   if (a < 1)
+     return 0;
+   if (a < Wtype_MAXp1_F)
+@@ -1334,8 +1338,6 @@
+       return (DWtype)counter << shift;
+     }
+   return -1;
+-#else
+-# error
+ #endif
+ }
+ #endif
+diff -urN gcc-4.6.4-clean/gcc/longlong.h gcc-4.6.4/gcc/longlong.h
+--- gcc-4.6.4-clean/gcc/longlong.h	2011-10-04 01:28:50.000000000 -0600
++++ gcc-4.6.4/gcc/longlong.h	2017-11-28 21:12:11.160911575 -0700
+@@ -528,6 +528,11 @@
+ 	   : "cbit")
+ #endif /* __M32R__ */
+ 
++#if defined (__m6309__) || defined (__m6809__)
++#define count_leading_zeros(COUNT,X)	((COUNT) = __builtin_clz (X))
++#define count_trailing_zeros(COUNT,X)	((COUNT) = __builtin_ctz (X))
++#endif
++
+ #if defined (__mc68000__) && W_TYPE_SIZE == 32
+ #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+   __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0"				\
+diff -urN gcc-4.6.4-clean/gcc/Makefile.in gcc-4.6.4/gcc/Makefile.in
+--- gcc-4.6.4-clean/gcc/Makefile.in	2013-04-01 02:32:34.000000000 -0600
++++ gcc-4.6.4/gcc/Makefile.in	2017-11-28 21:12:11.160911575 -0700
+@@ -2003,14 +2003,14 @@
+ 
+ # Compile the start modules crt0.o and mcrt0.o that are linked with
+ # every program
+-$(T)crt0.o: s-crt0 ; @true
+-$(T)mcrt0.o: s-crt0; @true
++crt0.o: s-crt0 ; @true
++mcrt0.o: s-crt0; @true
+ 
+ s-crt0:	$(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)crt0.o -c $(CRT0_S)
++	  -o crt0.o -c $(CRT0_S)
+ 	$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \
+-	  -o $(T)mcrt0.o -c $(MCRT0_S)
++	  -o mcrt0.o -c $(MCRT0_S)
+ 	$(STAMP) s-crt0
+ #
+ # Compiling object files from source files.
+diff -urN gcc-4.6.4-clean/gcc/opth-gen.awk gcc-4.6.4/gcc/opth-gen.awk
+--- gcc-4.6.4-clean/gcc/opth-gen.awk	2011-02-08 10:41:00.000000000 -0700
++++ gcc-4.6.4/gcc/opth-gen.awk	2017-11-28 21:12:11.160911575 -0700
+@@ -121,7 +121,7 @@
+ END {
+ print "/* This file is auto-generated by opth-gen.awk.  */"
+ print ""
+-print "#ifndef OPTIONS_H"
++print "#if !defined(OPTIONS_H) && !defined(IN_LIBGCC2)"
+ print "#define OPTIONS_H"
+ print ""
+ print "#include \"flag-types.h\""
+@@ -432,18 +432,9 @@
+ 
+ for (i = 0; i < n_opts; i++) {
+ 	opt = opt_args("InverseMask", flags[i])
+-	if (opt ~ ",") {
+-		vname = var_name(flags[i])
+-		macro = "OPTION_"
+-		mask = "OPTION_MASK_"
+-		if (vname == "") {
+-			vname = "target_flags"
+-			macro = "TARGET_"
+-			mask = "MASK_"
+-		}
+-		print "#define " macro nth_arg(1, opt) \
+-		      " ((" vname " & " mask nth_arg(0, opt) ") == 0)"
+-	}
++	if (opt ~ ",")
++		print "#define TARGET_" nth_arg(1, opt) \
++		      " ((target_flags & MASK_" nth_arg(0, opt) ") == 0)"
+ }
+ print ""
+ 
+diff -urN gcc-4.6.4-clean/gcc/tree.h gcc-4.6.4/gcc/tree.h
+--- gcc-4.6.4-clean/gcc/tree.h	2011-10-06 13:57:52.000000000 -0600
++++ gcc-4.6.4/gcc/tree.h	2017-11-28 21:12:11.160911575 -0700
+@@ -3563,6 +3563,8 @@
+   TI_UINTDI_TYPE,
+   TI_UINTTI_TYPE,
+ 
++  TI_UINT8_TYPE,
++  TI_UINT16_TYPE,
+   TI_UINT32_TYPE,
+   TI_UINT64_TYPE,
+ 
+diff -urN gcc-4.6.4-clean/gcc/version.c gcc-4.6.4/gcc/version.c
+--- gcc-4.6.4-clean/gcc/version.c	2009-04-21 13:03:23.000000000 -0600
++++ gcc-4.6.4/gcc/version.c	2017-11-29 17:11:34.133149157 -0700
+@@ -21,16 +21,16 @@
+ 
+ /* This is the location of the online document giving instructions for
+    reporting bugs.  If you distribute a modified version of GCC,
+-   please configure with --with-bugurl pointing to a document giving
+-   instructions for reporting bugs to you, not us.  (You are of course
+-   welcome to forward us bugs reported to you, if you determine that
+-   they are not bugs in your modifications.)  */
++   please change this to refer to a document giving instructions for
++   reporting bugs to you, not us.  (You are of course welcome to
++   forward us bugs reported to you, if you determine that they are
++   not bugs in your modifications.)  */
+ 
+-const char bug_report_url[] = BUGURL;
++const char bug_report_url[] = "<URL:http://lost.l-w.ca/coco/lwtools/>";
+ 
+ /* The complete version string, assembled from several pieces.
+    BASEVER, DATESTAMP, DEVPHASE, and REVISION are defined by the
+    Makefile.  */
+ 
+-const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION;
++const char version_string[] = BASEVER DATESTAMP DEVPHASE REVISION " (gcc6809lw pl9)";
+ const char pkgversion_string[] = PKGVERSION;
+diff -urN gcc-4.6.4-clean/libgcc/config.host gcc-4.6.4/libgcc/config.host
+--- gcc-4.6.4-clean/libgcc/config.host	2011-11-23 15:15:54.000000000 -0700
++++ gcc-4.6.4/libgcc/config.host	2017-11-28 21:12:11.160911575 -0700
+@@ -371,6 +371,8 @@
+  	;;
+ m32rle-*-linux*)
+ 	;;
++m6809*)
++	;;
+ m68hc11-*-*|m6811-*-*)
+         ;;
+ m68hc12-*-*|m6812-*-*)
+diff -urN gcc-4.6.4-clean/libgcc/fixed-obj.mk gcc-4.6.4/libgcc/fixed-obj.mk
+--- gcc-4.6.4-clean/libgcc/fixed-obj.mk	2007-09-17 16:18:13.000000000 -0600
++++ gcc-4.6.4/libgcc/fixed-obj.mk	2017-11-28 21:12:11.160911575 -0700
+@@ -23,7 +23,7 @@
+ #$(info $o$(objext): -DL$($o-label) $($o-opt))
+ 
+ $o$(objext): %$(objext): $(gcc_srcdir)/config/fixed-bit.c
+-	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide)
++	$(gcc_compile) -DL$($*-label) $($*-opt) -c $(gcc_srcdir)/config/fixed-bit.c $(vis_hide) -save-temps
+ 
+ ifeq ($(enable_shared),yes)
+ $(o)_s$(objext): %_s$(objext): $(gcc_srcdir)/config/fixed-bit.c
+diff -urN gcc-4.6.4-clean/libgcc/Makefile.in gcc-4.6.4/libgcc/Makefile.in
+--- gcc-4.6.4-clean/libgcc/Makefile.in	2012-12-04 12:11:33.000000000 -0700
++++ gcc-4.6.4/libgcc/Makefile.in	2017-11-28 21:12:11.160911575 -0700
+@@ -374,8 +374,8 @@
+ # Build lib2funcs.  For the static library also include LIB2FUNCS_ST.
+ lib2funcs-o = $(patsubst %,%$(objext),$(lib2funcs) $(LIB2FUNCS_ST))
+ $(lib2funcs-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(lib2funcs-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -410,8 +410,9 @@
+ # Build LIB2_DIVMOD_FUNCS.
+ lib2-divmod-o = $(patsubst %,%$(objext),$(LIB2_DIVMOD_FUNCS))
+ $(lib2-divmod-o): %$(objext): $(gcc_srcdir)/libgcc2.c
+-	$(gcc_compile) -DL$* -c $(gcc_srcdir)/libgcc2.c \
+-	  -fexceptions -fnon-call-exceptions $(vis_hide)
++	ln -sf $(gcc_srcdir)/libgcc2.c $*.c && \
++	$(gcc_compile) -DL$* -c $*.c \
++	  -fexceptions -fnon-call-exceptions $(vis_hide) -save-temps
+ libgcc-objects += $(lib2-divmod-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -443,7 +444,8 @@
+ ifneq ($(FPBIT),)
+ fpbit-o = $(patsubst %,%$(objext),$(FPBIT_FUNCS))
+ $(fpbit-o): %$(objext): $(FPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(FPBIT) $(vis_hide)
++	ln -sf $(FPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(fpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+@@ -458,7 +460,8 @@
+ ifneq ($(DPBIT),)
+ dpbit-o = $(patsubst %,%$(objext),$(DPBIT_FUNCS))
+ $(dpbit-o): %$(objext): $(DPBIT)
+-	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $(DPBIT) $(vis_hide)
++	ln -sf $(DPBIT) $*.c && \
++	$(gcc_compile) -DFINE_GRAINED_LIBRARIES -DL$* -c $*.c $(vis_hide) -save-temps
+ libgcc-objects += $(dpbit-o)
+ 
+ ifeq ($(enable_shared),yes)
+diff -urN gcc-4.6.4-clean/README.LW gcc-4.6.4/README.LW
+--- gcc-4.6.4-clean/README.LW	1969-12-31 17:00:00.000000000 -0700
++++ gcc-4.6.4/README.LW	2017-11-29 17:11:09.189248596 -0700
+@@ -0,0 +1,14 @@
++This is a port of gcc6809 which is designed to work with the lwtools
++cross-assembler and linker package.  You will need several scripts from that
++package, available at http://lost.l-w.ca/coco/lwtools/, in order to use
++this.  Instructions for building are present in the lwtools package.
++
++This work is based extensively on the gcc6809 4.3.4-3 release by Brian
++Dominy (brian@oddchange.com) with some significant renovations to make it
++work with gcc 4.6.4.
++
++There is no guarantee that it will work for any particular purpose you
++choose to put it to.
++
++If you run into any problems, contact William Astle (lost@l-w.ca). DO NOT
++contact the main GCC developers!
--- a/extra/ld	Mon Aug 05 21:07:14 2019 -0600
+++ b/extra/ld	Mon Aug 05 21:27:09 2019 -0600
@@ -43,7 +43,7 @@
 #		exe_suffix=.bin
 		;;
 	*)
-		options="--format=decb"
+		options="--format=raw"
 #		options="-b .text=0x8000 -b .data=0x1000 -b .bss=0x0100 -b .ctors=0xFD00 -b .dtors=0xFE00 -b vector=0xFFF0"
 #		aslink_options="-nwxso"
 #		exe_suffix=.s19
@@ -74,6 +74,10 @@
 		-o)
 			output_file=$1; shift
 			;;
+		--oformat=*)
+			arg=${arg#--oformat=};
+			options="$options --format=$arg"
+			;;
 		-L*)
 			arg=${arg#-L}
 			libpaths="$libpaths --library-path=$arg"
@@ -87,11 +91,17 @@
 			options="$options --section-base=$section_value"
 			;;
 		
-		--map)
-			map_file=$1; shift
-			options="$options --map=$map_file"
+		-Map=*)
+			arg=${arg#-Map=};
+			options="$options --map=$arg"
 			;;
 			
+		--script=*)
+			options="$options $arg"
+			;;
+		-T)
+			options="$options --script=$1"; shift
+			;;
 		-Tbss)
 			options="$options --section-base=.bss=$1"; shift
 			;;
@@ -109,16 +119,11 @@
 			;;
 		-g)
 			# Ignored by GNU ld; we should do the same
-			true
 			;;
 		-h|--help)
 			echo "ld (m6809)"
 			exit 0
 			;;
-		-T)
-			echo "-T scripts not supported";
-			exit 1;
-			;;
 		--format-lwex)
 			options="$options --format=lwex"
 			;;
@@ -140,6 +145,14 @@
 			options="$options $arg"
 			;;
 
+		--relax)
+			;;
+		--start-group)
+			;;
+		--end-group)
+			;;
+		--gc-sections)
+			;;
 		-*)
 			echo "ld (m6809): unknown option $arg"
 			exit 1
--- a/lwar/add.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/add.c	Mon Aug 05 21:27:09 2019 -0600
@@ -175,7 +175,7 @@
 		fseek(f2, 0, SEEK_END);
 		l = ftell(f2);
 		fseek(f2, 0, SEEK_SET);
-		fputs(files[i], f);
+		fputs(get_file_name(files[i]), f);
 		fputc(0, f);
 		fputc(l >> 24, f);
 		fputc((l >> 16) & 0xff, f);
--- a/lwar/extract.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/extract.c	Mon Aug 05 21:27:09 2019 -0600
@@ -30,6 +30,7 @@
 {
 	FILE *f;
 	char buf[8];
+	char *filename;
 	long l;
 	int c;
 	char fnbuf[1024];
@@ -78,6 +79,7 @@
 			}
 		}
 		fnbuf[i] = 0;
+		filename = get_file_name(fnbuf);
 		
 		// get length of archive member
 		l = 0;
@@ -92,16 +94,16 @@
 		
 		for (i = 0; i < nfiles; i++)
 		{
-			if (!strcmp(files[i], fnbuf))
+			if (!strcmp(get_file_name(files[i]), filename))
 				break;
 		}
 		if (i < nfiles || nfiles == 0)
 		{
 			// extract the file
-			nf = fopen(fnbuf, "wb");
+			nf = fopen(filename, "wb");
 			if (!nf)
 			{
-				fprintf(stderr, "Cannot extract '%s': %s\n", fnbuf, strerror(errno));
+				fprintf(stderr, "Cannot extract '%s': %s\n", filename, strerror(errno));
 				exit(1);
 			}
 			while (l)
--- a/lwar/lwar.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/lwar.c	Mon Aug 05 21:27:09 2019 -0600
@@ -24,9 +24,9 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <unistd.h>
 
 #include <lw_alloc.h>
 
@@ -43,6 +43,7 @@
 int nfiles = 0;
 char *archive_file = NULL;
 int mergeflag = 0;
+int filename_flag = 0;
 
 char **files = NULL;
 
@@ -52,3 +53,19 @@
 	files[nfiles] = fn;
 	nfiles++;
 }
+
+char *get_file_name(char *fn)
+{
+	char *filename;
+	if (filename_flag != 0)
+	{
+#ifdef _MSC_VER
+		filename = strrchr(fn, '\\');
+#else
+		filename = strrchr(fn, '/');
+#endif
+		if (filename != NULL)
+			return filename + 1;
+	}
+	return fn;
+}
--- a/lwar/lwar.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/lwar.h	Mon Aug 05 21:27:09 2019 -0600
@@ -39,6 +39,7 @@
 extern int nfiles;
 extern char **files;
 extern int mergeflag;
+extern int filename_flag;
 
 //typedef void * ARHANDLE;
 
@@ -55,6 +56,8 @@
 
 __lwar_E__ void add_file_name(char *fn);
 
+__lwar_E__ char *get_file_name(char *fn);
+
 //__lwar_E__ ARHANDLE open_archive(char *fn, int mode);
 
 #undef __lwar_E__
--- a/lwar/main.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/main.c	Mon Aug 05 21:27:09 2019 -0600
@@ -27,12 +27,18 @@
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#include <unistd.h>
 
 #include <lw_cmdline.h>
+#include <version.h>
 
 #include "lwar.h"
 
+#ifdef _MSC_VER
+#include <lw_win.h>	// windows build
+#else
+#include <unistd.h>
+#endif
+
 // command line option handling
 #define PROGVER "lwar from " PACKAGE_STRING
 char *program_name;
@@ -46,6 +52,11 @@
 		debug_level++;
 		break;
 	
+	case 'n':
+		// filename only, no path
+		filename_flag++;
+		break;
+	
 	case 'a':
 		// add members
 		operation = LWAR_OP_ADD;
@@ -85,6 +96,9 @@
 			archive_file = arg;
 		break;
 		
+	case lw_cmdline_key_end:
+		break;
+
 	default:
 		return lw_cmdline_err_unknown;
 	}
@@ -105,6 +119,8 @@
 				"Create new archive (or truncate existing one)" },
 	{ "merge",		'm',	0,		0,
 				"Add the contents of archive arguments instead of the archives themselves" },
+	{ "nopaths",	'n',	0,		0,
+				"Store only the filename when adding members and ignore the path, if any, when extracting members" },
 	{ "debug",		'd',	0,		0,
 				"Set debug mode"},
 	{ 0 }
@@ -130,7 +146,11 @@
 int main(int argc, char **argv)
 {
 	program_name = argv[0];
-	lw_cmdline_parse(&argparser, argc, argv, 0, 0, NULL);
+
+	if (lw_cmdline_parse(&argparser, argc, argv, 0, 0, NULL) != 0)
+	{
+		exit(1);
+	}
 	if (archive_file == NULL)
 	{
 		fprintf(stderr, "You must specify an archive file.\n");
--- a/lwar/replace.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwar/replace.c	Mon Aug 05 21:27:09 2019 -0600
@@ -23,7 +23,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+
+#ifdef _MSC_VER
+#include <lw_win.h>	// windows build
+#else
 #include <unistd.h>
+#endif
 
 #include "lwar.h"
 
@@ -32,6 +37,7 @@
 	FILE *f;
 	FILE *nf;
 	unsigned char buf[8];
+	char *filename;
 	long l;
 	int c;
 	FILE *f2;
@@ -101,6 +107,7 @@
 			}
 		}
 		fnbuf2[i] = 0;
+		filename = get_file_name(fnbuf2);
 		
 		// get length of archive member
 		l = 0;
@@ -116,7 +123,7 @@
 		// is it a file we are replacing? if so, do not copy it
 		for (i = 0; i < nfiles; i++)
 		{
-			if (!strcmp(files[i], fnbuf2))
+			if (!strcmp(get_file_name(files[i]), filename))
 				break;
 		}
 		if (i < nfiles)
@@ -126,7 +133,7 @@
 		else
 		{
 			// otherwise, copy it
-			fprintf(nf, "%s", fnbuf2);
+			fprintf(nf, "%s", filename);
 			fputc(0, nf);
 			fputc(l >> 24, nf);
 			fputc((l >> 16) & 0xff, nf);
@@ -215,7 +222,7 @@
 		fseek(f2, 0, SEEK_END);
 		l = ftell(f2);
 		fseek(f2, 0, SEEK_SET);
-		fputs(files[i], nf);
+		fputs(get_file_name(files[i]), nf);
 		fputc(0, nf);
 		fputc(l >> 24, nf);
 		fputc((l >> 16) & 0xff, nf);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/cycle.c	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,691 @@
+/*
+cycle.c
+
+Copyright (c) 2015 Erik Gavriluk
+Dual-licensed BSD 3-CLAUSE and GPL as per below.
+Thanks to John Kowalksi for cycle count verification.
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 of the License, or (at your option) any later
+version.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lwasm.h"
+
+typedef struct
+{
+	int opc;
+	int cycles_6809;
+	int cycles_6309;
+	cycle_flags flags;
+} cycletable_t;
+
+static cycletable_t cycletable[] =
+{
+	{ 0x3a, 3, 1, 0 },					// ABX
+
+	{ 0x89, 2, 2, 0 },					// ADCA
+	{ 0x99, 4, 3, 0 },
+	{ 0xa9, 4, 4, CYCLE_ADJ },
+	{ 0xb9, 5, 4, 0 },
+
+	{ 0xc9, 2, 2, 0 },					// ADCB
+	{ 0xd9, 4, 3, 0 },
+	{ 0xe9, 4, 4, CYCLE_ADJ },
+	{ 0xf9, 5, 4, 0 },
+
+	{ 0x1089, 5, 4, 0 },				// ADCD
+	{ 0x1099, 7, 5, 0 },
+	{ 0x10a9, 7, 6, CYCLE_ADJ },
+	{ 0x10b9, 8, 6, 0 },
+
+	{ 0x8b, 2, 2, 0 },					// ADDA
+	{ 0x9b, 4, 3, 0 },
+	{ 0xab, 4, 4, CYCLE_ADJ },
+	{ 0xbb, 5, 4, 0 },
+
+	{ 0xcb, 2, 2, 0 },					// ADDB
+	{ 0xdb, 4, 3, 0 },
+	{ 0xeb, 4, 4, CYCLE_ADJ },
+	{ 0xfb, 5, 4, 0 },
+
+	{ 0xc3, 4, 3, 0 },					// ADDD
+	{ 0xd3, 6, 4, 0 },
+	{ 0xe3, 6, 5, CYCLE_ADJ },
+	{ 0xf3, 7, 5, 0 },
+
+	{ 0x118b, 3, 3, 0 },				// ADDE
+	{ 0x119b, 5, 4, 0 },
+	{ 0x11ab, 5, 5, CYCLE_ADJ },
+	{ 0x11bb, 6, 5, 0 },
+
+	{ 0x11cb, 3, 3, 0 },				// ADDF
+	{ 0x11db, 5, 4, 0 },
+	{ 0x11eb, 5, 5, CYCLE_ADJ },
+	{ 0x11fb, 6, 5, 0 },
+
+	{ 0x1031, 4, 4, 0 },				// ADCR
+	{ 0x1030, 4, 4, 0 },				// ADDR
+	{ 0x1034, 4, 4, 0 },				// ANDR
+	{ 0x1037, 4, 4, 0 },				// CMPR
+	{ 0x1036, 4, 4, 0 },				// EORR
+	{ 0x1035, 4, 4, 0 },				// ORR
+	{ 0x1033, 4, 4, 0 },				// SBCR
+	{ 0x1032, 4, 4, 0 },				// SUBR
+
+	{ 0x108b, 5, 4, 0 },				// ADDW
+	{ 0x109b, 7, 5, 0 },
+	{ 0x10ab, 7, 6, CYCLE_ADJ },
+	{ 0x10bb, 8, 6, 0 },
+
+	{ 0x02, 6, 6, 0 },					// AIM
+	{ 0x62, 7, 7, CYCLE_ADJ },
+	{ 0x72, 7, 7, 0 },
+
+	{ 0x84, 2, 2, 0 },					// ANDA
+	{ 0x94, 4, 3, 0 },
+	{ 0xa4, 4, 4, CYCLE_ADJ },
+	{ 0xb4, 5, 4, 0 },
+
+	{ 0xc4, 2, 2, 0 },					// ANDB
+	{ 0xd4, 4, 3, 0 },
+	{ 0xe4, 4, 4, CYCLE_ADJ },
+	{ 0xf4, 5, 4, 0 },
+
+	{ 0x1c, 3, 2, 0 },					// ANDCC
+
+	{ 0x1084, 5, 4, 0 },				// ANDD
+	{ 0x1094, 7, 5, 0 },
+	{ 0x10a4, 7, 6, CYCLE_ADJ },
+	{ 0x10b4, 8, 6, 0 },
+
+	{ 0x48, 2, 1, 0 },					// ASL
+	{ 0x58, 2, 1, 0 },
+	{ 0x1048, 3, 2, 0 },
+	{ 0x08, 6, 5, 0 },
+	{ 0x68, 6, 6, CYCLE_ADJ },
+	{ 0x78, 7, 6, 0 },
+
+	{ 0x47, 2, 1, 0 },					// ASR
+	{ 0x57, 2, 1, 0 },
+	{ 0x1047, 3, 2, 0 },
+	{ 0x07, 6, 5, 0 },
+	{ 0x67, 6, 6, CYCLE_ADJ },
+	{ 0x77, 7, 6, 0 },
+
+	{ 0x1130, 7, 6, 0 },				// BAND
+	{ 0x1131, 7, 6, 0 },				// BIAND
+	{ 0x1132, 7, 6, 0 },				// BOR
+	{ 0x1133, 7, 6, 0 },				// BIOR
+	{ 0x1134, 7, 6, 0 },				// BEOR
+	{ 0x1135, 7, 6, 0 },				// BIEOR
+
+	{ 0x85, 2, 2, 0 },					// BITA
+	{ 0x95, 4, 3, 0 },
+	{ 0xa5, 4, 4, CYCLE_ADJ },
+	{ 0xb5, 5, 4, 0 },
+
+	{ 0xc5, 2, 2, 0 },					// BITB
+	{ 0xd5, 4, 3, 0 },
+	{ 0xe5, 4, 4, CYCLE_ADJ },
+	{ 0xf5, 5, 4, 0 },
+
+	{ 0x1085, 5, 4, 0 },				// BITD
+	{ 0x1095, 7, 5, 0 },
+	{ 0x10a5, 7, 6, CYCLE_ADJ },
+	{ 0x10b5, 8, 6, 0 },
+
+	{ 0x113c, 4, 4, 0 },				// BITMD
+
+	{ 0x20, 3, 3, 0 },					// BRA
+	{ 0x21, 3, 3, 0 },
+	{ 0x22, 3, 3, 0 },
+	{ 0x23, 3, 3, 0 },
+	{ 0x24, 3, 3, 0 },
+	{ 0x25, 3, 3, 0 },
+	{ 0x26, 3, 3, 0 },
+	{ 0x27, 3, 3, 0 },
+	{ 0x28, 3, 3, 0 },
+	{ 0x29, 3, 3, 0 },
+	{ 0x2a, 3, 3, 0 },
+	{ 0x2b, 3, 3, 0 },
+	{ 0x2c, 3, 3, 0 },
+	{ 0x2d, 3, 3, 0 },
+	{ 0x2e, 3, 3, 0 },
+	{ 0x2f, 3, 3, 0 },
+
+	{ 0x8d, 7, 6, 0 },					// BSR
+
+	{ 0x4f, 2, 1, 0 },					// CLR
+	{ 0x5f, 2, 1, 0 },
+	{ 0x104f, 3, 2, 0 },
+	{ 0x114f, 3, 2, 0 },
+	{ 0x115f, 3, 2, 0 },
+	{ 0x105f, 3, 2, 0 },
+	{ 0x0f, 6, 5, 0 },
+	{ 0x6f, 6, 6, CYCLE_ADJ },
+	{ 0x7f, 7, 6, 0 },
+
+	{ 0x81, 2, 2, 0 },					// CMPA
+	{ 0x91, 4, 3, 0 },
+	{ 0xa1, 4, 4, CYCLE_ADJ },
+	{ 0xb1, 5, 4, 0 },
+
+	{ 0xc1, 2, 2, 0 },					// CMPB
+	{ 0xd1, 4, 3, 0 },
+	{ 0xe1, 4, 4, CYCLE_ADJ },
+	{ 0xf1, 5, 4, 0 },
+
+	{ 0x1083, 5, 4, 0 },				// CMPD
+	{ 0x1093, 7, 5, 0 },
+	{ 0x10a3, 7, 6, CYCLE_ADJ },
+	{ 0x10b3, 8, 6, 0 },
+
+	{ 0x1181, 3, 3, 0 },				// CMPE
+	{ 0x1191, 5, 4, 0 },
+	{ 0x11a1, 5, 5, CYCLE_ADJ },
+	{ 0x11b1, 6, 5, 0 },
+
+	{ 0x11c1, 3, 3, 0 },				// CMPF
+	{ 0x11d1, 5, 4, 0 },
+	{ 0x11e1, 5, 5, CYCLE_ADJ },
+	{ 0x11f1, 6, 5, 0 },
+
+	{ 0x118c, 5, 4, 0 },				// CMPS
+	{ 0x119c, 7, 5, 0 },
+	{ 0x11ac, 7, 6, CYCLE_ADJ },
+	{ 0x11bc, 8, 6, 0 },
+
+	{ 0x1183, 5, 4, 0 },				// CMPU
+	{ 0x1193, 7, 5, 0 },
+	{ 0x11a3, 7, 6, CYCLE_ADJ },
+	{ 0x11b3, 8, 6, 0 },
+
+	{ 0x1081, 5, 4, 0 },				// CMPW
+	{ 0x1091, 7, 5, 0 },
+	{ 0x10a1, 7, 6, CYCLE_ADJ },
+	{ 0x10b1, 8, 6, 0 },
+
+	{ 0x8c, 4, 3, 0 },					// CMPX
+	{ 0x9c, 6, 4, 0 },
+	{ 0xac, 6, 5, CYCLE_ADJ },
+	{ 0xbc, 7, 5, 0 },
+
+	{ 0x108c, 5, 4, 0 },				// CMPY
+	{ 0x109c, 7, 5, 0 },
+	{ 0x10ac, 7, 6, CYCLE_ADJ },
+	{ 0x10bc, 8, 6, 0 },
+
+	{ 0x43, 2, 1, 0 },					// COMA
+	{ 0x53, 2, 1, 0 },					// COMB
+	{ 0x1043, 3, 2, 0 },				// COMD
+	{ 0x1143, 3, 2, 0 },				// COME
+	{ 0x1153, 3, 2, 0 },				// COMF
+	{ 0x1053, 3, 2, 0 },				// COMW
+
+	{ 0x03, 6, 5, 0 },					// COM
+	{ 0x63, 6, 6, CYCLE_ADJ },
+	{ 0x73, 7, 6, 0 },
+
+	{ 0x3c, 22, 20, CYCLE_ESTIMATED },	// CWAI
+
+	{ 0x19, 2, 1, 0 },					// DAA
+
+	{ 0x4a, 2, 1, 0 },					// DECA
+	{ 0x5a, 2, 1, 0 },					// DECB
+	{ 0x104a, 3, 2, 0 },				// DECD
+	{ 0x114a, 3, 2, 0 },				// DECE
+	{ 0x115a, 3, 2, 0 },				// DECF
+	{ 0x105a, 3, 2, 0 },				// DECW
+
+	{ 0x0a, 6, 5, 0 },					// DEC
+	{ 0x6a, 6, 6, CYCLE_ADJ },
+	{ 0x7a, 7, 6, 0 },
+
+	{ 0x118d, 25, 25, 0 },				// DIVD
+	{ 0x119d, 27, 26, 0 },
+	{ 0x11ad, 27, 27, CYCLE_ADJ },
+	{ 0x11bd, 28, 27, 0 },
+
+	{ 0x118e, 34, 34, 0 },				// DIVQ
+	{ 0x119e, 36, 35, 0 },
+	{ 0x11ae, 36, 36, 0 },
+	{ 0x11be, 37, 36, 0 },
+
+	{ 0x05, 6, 6, 0 },					// EIM
+	{ 0x65, 7, 7, CYCLE_ADJ },
+	{ 0x75, 7, 7, 0 },
+
+	{ 0x88, 2, 2, 0 },					// EORA
+	{ 0x98, 4, 3, 0 },
+	{ 0xa8, 4, 4, CYCLE_ADJ },
+	{ 0xb8, 5, 4, 0 },
+
+	{ 0xc8, 2, 2, 0 },					// EORB
+	{ 0xd8, 4, 3, 0 },
+	{ 0xe8, 4, 4, CYCLE_ADJ },
+	{ 0xf8, 5, 4, 0 },
+
+	{ 0x1088, 5, 4, 0 },				// EORD
+	{ 0x1098, 7, 5, 0 },
+	{ 0x10a8, 7, 6, CYCLE_ADJ },
+	{ 0x10b8, 8, 6, 0 },
+
+	{ 0x1e, 8, 5, 0 },					// EXG
+
+	{ 0x4c, 2, 1, 0 },					// INCA
+	{ 0x5c, 2, 1, 0 },					// INCB
+	{ 0x104c, 3, 2, 0 },				// INCD
+	{ 0x114c, 3, 2, 0 },				// INCE
+	{ 0x115c, 3, 2, 0 },				// INCF
+	{ 0x105c, 3, 2, 0 },				// INCW
+
+	{ 0x0c, 6, 5, 0 },					// INC
+	{ 0x6c, 6, 6, CYCLE_ADJ },
+	{ 0x7c, 7, 6, 0 },
+
+	{ 0x0e, 3, 2, 0 },					// JMP
+	{ 0x6e, 3, 3, CYCLE_ADJ },
+	{ 0x7e, 4, 3, 0 },
+
+	{ 0x9d, 7, 6, 0 },					// JSR
+	{ 0xad, 7, 6, CYCLE_ADJ },
+	{ 0xbd, 8, 7, 0 },
+
+	{ 0x16, 5, 4, 0 },					// LBRA
+	{ 0x17, 9, 7, 0 },					// LBSR
+	{ 0x1021, 5, 5, 0 },				// LBRN
+	{ 0x1022, 5, 5, 0 },				// remaining long branches are estimated on 6809 only:
+	{ 0x1023, 5, 5, 0 },				//
+	{ 0x1024, 5, 5, 0 },				// 6809: 5 cycles, +1 cycle if the branch is taken
+	{ 0x1025, 5, 5, 0 },				// 6309 native: always 5 cycles
+	{ 0x1026, 5, 5, 0 },				//
+	{ 0x1027, 5, 5, 0 },				// this is handled as a special case elsewhere
+	{ 0x1028, 5, 5, 0 },		
+	{ 0x1029, 5, 5, 0 },		
+	{ 0x102a, 5, 5, 0 },
+	{ 0x102b, 5, 5, 0 },
+	{ 0x102c, 5, 5, 0 },
+	{ 0x102d, 5, 5, 0 },
+	{ 0x102e, 5, 5, 0 },
+	{ 0x102f, 5, 5, 0 },
+
+	{ 0x86, 2, 2, 0 },					// LDA
+	{ 0x96, 4, 3, 0 },
+	{ 0xa6, 4, 4, CYCLE_ADJ },
+	{ 0xb6, 5, 4, 0 },
+
+	{ 0xc6, 2, 2, 0 },					// LDB
+	{ 0xd6, 4, 3 },
+	{ 0xe6, 4, 4, CYCLE_ADJ },
+	{ 0xf6, 5, 4, 0 },
+
+	{ 0x1136, 7, 6, 0 },				// LDBT
+
+	{ 0xcc, 3, 3, 0 },					// LDD
+	{ 0xdc, 5, 4, 0 },
+	{ 0xec, 5, 5, CYCLE_ADJ },
+	{ 0xfc, 6, 5, 0 },
+
+	{ 0x1186, 3, 3, 0 },				// LDE
+	{ 0x1196, 5, 4, 0 },
+	{ 0x11a6, 5, 5, CYCLE_ADJ },
+	{ 0x11b6, 6, 5, 0 },
+
+	{ 0x11c6, 3, 3, 0 },				// LDF
+	{ 0x11d6, 5, 4, 0 },
+	{ 0x11e6, 5, 5, CYCLE_ADJ },
+	{ 0x11f6, 6, 5, 0 },
+
+	{ 0xcd, 5, 5, 0 },					// LDQ
+	{ 0x10dc, 8, 7, 0 },
+	{ 0x10ec, 8, 8, CYCLE_ADJ },
+	{ 0x10fc, 9, 8, 0 },
+
+	{ 0x10ce, 4, 4, 0 },				// LDS
+	{ 0x10de, 6, 5, 0 },
+	{ 0x10ee, 6, 6, CYCLE_ADJ },
+	{ 0x10fe, 7, 6, 0 },
+
+	{ 0xce, 3, 3, 0 },					// LDU
+	{ 0xde, 5, 4, 0 },
+	{ 0xee, 5, 5, CYCLE_ADJ },
+	{ 0xfe, 6, 5, 0 },
+
+	{ 0x1086, 4, 4, 0 },				// LDW
+	{ 0x1096, 6, 5, 0 },
+	{ 0x10a6, 6, 6, CYCLE_ADJ },
+	{ 0x10b6, 7, 6, 0 },
+
+	{ 0x8e, 3, 3, 0 },					// LDX
+	{ 0x9e, 5, 4, 0 },
+	{ 0xae, 5, 5, CYCLE_ADJ },
+	{ 0xbe, 6, 5, 0 },
+
+	{ 0x108e, 4, 4, 0 },				// LDY
+	{ 0x109e, 6, 5, 0 },
+	{ 0x10ae, 6, 6, CYCLE_ADJ },
+	{ 0x10be, 7, 6, 0 },
+
+	{ 0x113d, 5, 5, 0 },				// LDMD
+
+	{ 0x30, 4, 4, CYCLE_ADJ },			// LEA
+	{ 0x31, 4, 4, CYCLE_ADJ },
+	{ 0x32, 4, 4, CYCLE_ADJ },
+	{ 0x33, 4, 4, CYCLE_ADJ },
+
+	{ 0x44, 2, 1, 0 },					// LSRA
+	{ 0x54, 2, 1, 0 },					// LSRB
+	{ 0x1044, 3, 2, 0 },				// LSRD
+	{ 0x1054, 3, 2, 0 },				// LSRW
+
+	{ 0x04, 6, 5, 0 },					// LSR
+	{ 0x64, 6, 6, CYCLE_ADJ },
+	{ 0x74, 7, 6, 0 },
+
+	{ 0x3d, 11, 10, 0 },				// MUL
+
+	{ 0x118f, 28, 28, 0 },				// MULD
+	{ 0x119f, 30, 29, 0 },	
+	{ 0x11af, 30, 30, CYCLE_ADJ },
+	{ 0x11bf, 31, 30, 0 },
+
+	{ 0x40, 2, 1, 0 },					// NEGA
+	{ 0x50, 2, 1, 0 },					// NEGB
+	{ 0x1040, 3, 2, 0 },				// NEGD
+
+	{ 0x00, 6, 5, 0 },					// NEG
+	{ 0x60, 6, 6, CYCLE_ADJ },
+	{ 0x70, 7, 6, 0 },
+
+	{ 0x12, 2, 1, 0 },					// NOP
+
+	{ 0x01, 6, 6, 0 },					// OIM
+	{ 0x61, 7, 7, CYCLE_ADJ },
+	{ 0x71, 7, 7, 0 },
+
+	{ 0x8a, 2, 2, 0 },					// ORA
+	{ 0x9a, 4, 3, 0 },
+	{ 0xaa, 4, 4, CYCLE_ADJ },
+	{ 0xba, 5, 4, 0 },
+
+	{ 0xca, 2, 2, 0 },					// ORB
+	{ 0xda, 4, 3, 0 },
+	{ 0xea, 4, 4, CYCLE_ADJ },
+	{ 0xfa, 5, 4, 0 },
+
+	{ 0x1a, 3, 2, 0 },					// ORCC
+
+	{ 0x108a, 5, 4, 0 },				// ORD
+	{ 0x109a, 7, 5, 0 },
+	{ 0x10aa, 7, 6, CYCLE_ADJ },
+	{ 0x10ba, 8, 6, 0 },
+
+	{ 0x34, 5, 4, CYCLE_ADJ },			// PSHS
+	{ 0x36, 5, 4, CYCLE_ADJ },			// PSHU
+	{ 0x35, 5, 4, CYCLE_ADJ },			// PULS
+	{ 0x37, 5, 4, CYCLE_ADJ },			// PULU
+	{ 0x1038, 6, 6, 0 },				// PSHSW
+	{ 0x103a, 6, 6, 0 },				// PSHUW
+	{ 0x1039, 6, 6, 0 },				// PULSW
+	{ 0x103b, 6, 6, 0 },				// PULUW
+
+	{ 0x49, 2, 1, 0 },					// ROLA
+	{ 0x59, 2, 1, 0 },					// ROLB
+	{ 0x1049, 3, 2, 0 },				// ROLD
+	{ 0x1059, 3, 2, 0 },				// ROLW
+
+	{ 0x09, 6, 5, 0 },					// ROL
+	{ 0x69, 6, 6, CYCLE_ADJ },
+	{ 0x79, 7, 6, 0 },
+
+	{ 0x46, 2, 1, 0 },					// RORA
+	{ 0x56, 2, 1, 0 },					// RORB
+	{ 0x1046, 3, 2, 0 },				// RORD
+	{ 0x1056, 3, 2, 0 },				// RORW
+
+	{ 0x06, 6, 5, 0 },					// ROR
+	{ 0x66, 6, 6, CYCLE_ADJ },
+	{ 0x76, 7, 6, 0 },
+
+	{ 0x3b, 6, 17, CYCLE_ESTIMATED },	// RTI
+
+	{ 0x39, 5, 4, 0 },					// RTS
+
+	{ 0x82, 2, 2, 0 },					// SBCA
+	{ 0x92, 4, 3, 0 },
+	{ 0xa2, 4, 4, CYCLE_ADJ },
+	{ 0xb2, 5, 4, 0 },
+
+	{ 0xc2, 2, 2, 0 },					// SBCB
+	{ 0xd2, 4, 3, 0 },
+	{ 0xe2, 4, 4, CYCLE_ADJ },
+	{ 0xf2, 5, 4, 0 },
+
+	{ 0x1082, 5, 4, 0 },				// SBCD
+	{ 0x1092, 7, 5, 0 },
+	{ 0x10a2, 7, 6, CYCLE_ADJ },
+	{ 0x10b2, 8, 6, 0 },
+
+	{ 0x1d, 2, 1, 0 },					// SEX
+	{ 0x14, 4, 4, 0 },					// SEXW
+
+	{ 0x97, 4, 3, 0 },					// STA
+	{ 0xa7, 4, 4, CYCLE_ADJ },
+	{ 0xb7, 5, 4, 0 },
+
+	{ 0xd7, 4, 3, 0 },					// STB
+	{ 0xe7, 4, 4, CYCLE_ADJ },
+	{ 0xf7, 5, 4, 0 },
+
+	{ 0x1137, 8, 7, 0 },				// STBT
+
+	{ 0xdd, 5, 4, 0 },					// STD
+	{ 0xed, 5, 5, CYCLE_ADJ },
+	{ 0xfd, 6, 5, 0 },
+
+	{ 0x1197, 5, 4, 0 },				// STE
+	{ 0x11a7, 5, 5, CYCLE_ADJ },
+	{ 0x11b7, 6, 5, 0 },
+
+	{ 0x11d7, 5, 4, 0 },				// STF
+	{ 0x11e7, 5, 5, CYCLE_ADJ },
+	{ 0x11f7, 6, 5, 0 },
+
+	{ 0x10dd, 8, 7, 0 },				// STQ
+	{ 0x10ed, 8, 8, CYCLE_ADJ },
+	{ 0x10fd, 9, 8, 0 },
+
+	{ 0x10df, 6, 5, 0 },				// STS
+	{ 0x10ef, 6, 6, CYCLE_ADJ },
+	{ 0x10ff, 7, 6, 0 },
+
+	{ 0xdf, 5, 4, 0 },					// STU
+	{ 0xef, 5, 5, CYCLE_ADJ },
+	{ 0xff, 6, 5, 0 },
+
+	{ 0x1097, 6, 5, 0 },				// STW
+	{ 0x10a7, 6, 6, CYCLE_ADJ },
+	{ 0x10b7, 7, 6, 0 },
+
+	{ 0x9f, 5, 4, 0 },					// STX
+	{ 0xaf, 5, 5, CYCLE_ADJ },
+	{ 0xbf, 6, 5, 0 },
+
+	{ 0x109f, 6, 5, 0 },				// STY
+	{ 0x10af, 6, 6, CYCLE_ADJ },
+	{ 0x10bf, 7, 6, 0 },
+
+	{ 0x80, 2, 2, 0 },					// SUBA
+	{ 0x90, 4, 3, 0 },
+	{ 0xa0, 4, 4, CYCLE_ADJ },
+	{ 0xb0, 5, 4, 0 },
+
+	{ 0xc0, 2, 2, 0 },					// SUBB
+	{ 0xd0, 4, 3, 0 },
+	{ 0xe0, 4, 4, CYCLE_ADJ },
+	{ 0xf0, 5, 4, 0 },
+
+	{ 0x83, 4, 3, 0 },					// SUBD
+	{ 0x93, 6, 4, 0 },
+	{ 0xa3, 6, 5, CYCLE_ADJ },
+	{ 0xb3, 7, 5, 0 },
+
+	{ 0x1180, 3, 3, 0 },				// SUBE
+	{ 0x1190, 5, 4, 0 },
+	{ 0x11a0, 5, 5, CYCLE_ADJ },
+	{ 0x11b0, 6, 5, 0 },
+
+	{ 0x11c0, 3, 3, 0 },				// SUBF
+	{ 0x11d0, 5, 4, 0 },
+	{ 0x11e0, 5, 5, CYCLE_ADJ },
+	{ 0x11f0, 6, 5, 0 },
+
+	{ 0x1080, 5, 4, 0 },				// SUBW
+	{ 0x1090, 7, 5, 0 },
+	{ 0x10a0, 7, 6, CYCLE_ADJ },
+	{ 0x10b0, 8, 6, 0 },
+
+	{ 0x3f, 19, 21, 0 },				// SWI
+	{ 0x103f, 20, 22, 0 },				// SWI2
+	{ 0x113f, 20, 22, 0 },				// SWI3
+
+	{ 0x13, 2, 1, CYCLE_ESTIMATED },	// SYNC
+
+	{ 0x1f, 6, 4, 0 },					// TFR
+
+	{ 0x0b, 6, 6, 0 },				// TIM
+	{ 0x6b, 7, 7, CYCLE_ADJ },
+	{ 0x7b, 7, 7, 0 },
+
+	{ 0x1138, 6, 6, CYCLE_ESTIMATED },	// TFM
+	{ 0x1139, 6, 6, CYCLE_ESTIMATED },	
+	{ 0x113a, 6, 6, CYCLE_ESTIMATED },	
+	{ 0x113b, 6, 6, CYCLE_ESTIMATED },	
+
+	{ 0x4d, 2, 1, 0 },					// TSTA
+	{ 0x5d, 2, 1, 0 },					// TSTB
+	{ 0x104d, 3, 2, 0 },				// TSTD
+	{ 0x114d, 3, 2, 0 },				// TSTE
+	{ 0x115d, 3, 2, 0 },				// TSTF
+	{ 0x105d, 3, 2, 0 },				// TSTW
+
+	{ 0x0d, 6, 4, 0 },					// TST
+	{ 0x6d, 6, 5, CYCLE_ADJ },
+	{ 0x7d, 7, 5, 0 },
+
+	{ -1, -1 }
+};
+
+typedef struct
+{
+	int cycles_6809_indexed;
+	int cycles_6309_indexed;
+	int cycles_6809_indirect;
+	int cycles_6309_indirect;
+} indtab_t;
+
+static indtab_t indtab[] =
+{
+	{ 2, 1, -1, -1, },	// 0000		,R+   
+	{ 3, 2, 6, 6, },	// 0001		,R++	[,R++]
+	{ 2, 1, -1, -1, },	// 0010		,-R   
+	{ 3, 2, 6, 6, },	// 0011		,--R	[,--R]
+	{ 0, 0, 3, 3, },	// 0100		,R		[,R]
+	{ 1, 1, 4, 4, },	// 0101		B,R		[B,R]
+	{ 1, 1, 4, 4, },	// 0110		A,R		[A,R]
+	{ 1, 1, 1, 1, },	// 0111		E,R		[E,R]
+	{ 1, 1, 4, 4, },	// 1000		n,R		[n,R]
+	{ 4, 3, 7, 7, },	// 1001		n,R		[n,R]  (16 bit)
+	{ 1, 1, 1, 1, },	// 1010		F,R		[F,R] 
+	{ 4, 2, 4, 4, },	// 1011		D,R		[D,R] 
+	{ 1, 1, 4, 4, },	// 1100		n,PC	[n,PC]
+	{ 5, 3, 8, 8, },	// 1101		n,PC	[n,PC] (16 bit)
+	{ 4, 1, 4, 4, },	// 1110		W,R		[W,R]
+	{ -1, -1, 5, 5, },	// 1111				[n]	   (16 bit)
+};
+
+/* calculates additional ticks from post byte in both indexed and indirect modes */
+int lwasm_cycle_calc_ind(line_t *cl)
+{
+	int pb = cl->pb;
+
+	if ((pb & 0x80) == 0) /* 5 bit offset */
+		return 1;
+
+	// These need special handling because the *register* bits determine the specific operation (and, thus, cycle counts)
+	if (!CURPRAGMA(cl, PRAGMA_6809))
+	{
+		switch (pb)
+		{
+		case 0x8f:  // ,W
+			return 0;
+		case 0xaf:  // n,W (16 bit)
+			return 2;
+		case 0xcf:  // ,W++
+		case 0xef:  // ,--W
+			return 1;
+		case 0x90:  // [,W]
+			return 3;
+		case 0xb0: // [n,W] (16 bit)
+			return 5;
+		case 0xd0: // [,W++]
+		case 0xf0: // [,--W]
+			return 4;
+		}
+	}
+
+	if (pb & 0x10) /* indirect */
+		return CURPRAGMA(cl, PRAGMA_6809) ? indtab[pb & 0xf].cycles_6809_indirect : indtab[pb & 0xf].cycles_6309_indirect;
+	else
+		return CURPRAGMA(cl, PRAGMA_6809) ? indtab[pb & 0xf].cycles_6809_indexed : indtab[pb & 0xf].cycles_6309_indexed;
+}
+
+/* calculate additional ticks from post byte in rlist (PSHS A,B,X...) */
+int lwasm_cycle_calc_rlist(line_t *cl)
+{
+	int i, cycles = 0;
+
+	for (i = 0; i < 8; i++)
+	{
+		// 1 cycle for 8 bit regs CC-DP (bits 0-3)
+		// otherwise 2
+		if (cl->pb & 1 << i)
+			cycles += (i <= 3) ? 1 : 2;
+	}
+
+	return cycles;
+}
+
+void lwasm_cycle_update_count(line_t *cl, int opc)
+{
+	int i;
+	for (i = 0; 1; i++)
+	{
+		if (cycletable[i].opc == -1) return;
+
+		if (cycletable[i].opc == opc)
+		{
+			cl->cycle_base = CURPRAGMA(cl, PRAGMA_6809) ? cycletable[i].cycles_6809 : cycletable[i].cycles_6309;
+			cl->cycle_flags = cycletable[i].flags;
+			cl->cycle_adj = 0;
+
+			// long branches are estimated on 6809
+			if (CURPRAGMA(cl, PRAGMA_6809) && (opc >= 0x1022 && opc <= 0x102f))
+				cl->cycle_flags |= CYCLE_ESTIMATED;
+
+			return;
+		}
+	}
+}
--- a/lwasm/debug.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/debug.c	Mon Aug 05 21:27:09 2019 -0600
@@ -19,6 +19,8 @@
 this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
+#ifndef LWASM_NODEBUG
+
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
@@ -72,7 +74,7 @@
 	}
 }
 
-void debug_message(asmstate_t *as, int level, const char *fmt, ...)
+void real_debug_message(asmstate_t *as, int level, const char *fmt, ...)
 {
 	va_list args;
 
@@ -90,3 +92,5 @@
 
 	va_end(args);
 }
+
+#endif
--- a/lwasm/input.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/input.c	Mon Aug 05 21:27:09 2019 -0600
@@ -82,6 +82,11 @@
 
 struct ifl *ifl_head = NULL;
 
+int input_isinclude(asmstate_t *as)
+{
+	return IS->type == input_type_include;
+}
+
 static int input_isabsolute(const char *s)
 {
 #if defined(WIN32) || defined(WIN64)
--- a/lwasm/input.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/input.h	Mon Aug 05 21:27:09 2019 -0600
@@ -29,15 +29,16 @@
   int magic;
 } input_stack_entry;
 
-extern void input_stack_push(asmstate_t *as, input_stack_entry *se);
-extern input_stack_entry *input_stack_pop(asmstate_t *as, int magic, int (*fn)(input_stack_entry *e, void *data), void *data);
+void input_stack_push(asmstate_t *as, input_stack_entry *se);
+input_stack_entry *input_stack_pop(asmstate_t *as, int magic, int (*fn)(input_stack_entry *e, void *data), void *data);
 
-extern void input_init(asmstate_t *as);
-extern void input_openstring(asmstate_t *as, char *s, char *str);
-extern void input_open(asmstate_t *as, char *s);
-extern char *input_readline(asmstate_t *as);
-extern char *input_curspec(asmstate_t *as);
-extern FILE *input_open_standalone(asmstate_t *as, char *s, char **rfn);
+void input_init(asmstate_t *as);
+void input_openstring(asmstate_t *as, char *s, char *str);
+void input_open(asmstate_t *as, char *s);
+char *input_readline(asmstate_t *as);
+char *input_curspec(asmstate_t *as);
+FILE *input_open_standalone(asmstate_t *as, char *s, char **rfn);
+int input_isinclude(asmstate_t *as);
 
 struct ifl
 {
@@ -45,6 +46,6 @@
 	struct ifl *next;
 };
 
-extern struct ifl *ifl_head;
+struct ifl *ifl_head;
 
 #endif
--- a/lwasm/insn_bitbit.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_bitbit.c	Mon Aug 05 21:27:09 2019 -0600
@@ -46,42 +46,42 @@
 	}
 	else
 	{
-		lwasm_register_error(as, l, "Bad register");
+		lwasm_register_error(as, l, E_REGISTER_BAD);
 		return;
 	}
-	
+	lwasm_skip_to_next_token(l, p);
 	if (*(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 0, e);
 	if (*(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 1, e);
 
 	if (*(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
-
+	lwasm_skip_to_next_token(l, p);
 	// ignore base page address modifier
 	if (**p == '<')
 		(*p)++;
@@ -89,7 +89,7 @@
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 2, e);
@@ -106,26 +106,26 @@
 	e = lwasm_fetch_expr(l, 0);
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
-		lwasm_register_error(as, l, "Bit number must be fully resolved");
+		lwasm_register_error(as, l, E_BITNUMBER_UNRESOLVED);
 		return;
 	}
 	v1 = lw_expr_intval(e);
 	if (v1 < 0 || v1 > 7)
 	{
-		lwasm_register_error(as, l, "Invalid bit number");
+		lwasm_register_error(as, l, E_BITNUMBER_INVALID);
 		v1 = 0;
 	}
 
 	e = lwasm_fetch_expr(l, 1);
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
-		lwasm_register_error(as, l, "Bit number must be fully resolved");
+		lwasm_register_error(as, l, E_BITNUMBER_UNRESOLVED);
 		return;
 	}
 	v2 = lw_expr_intval(e);
 	if (v2 < 0 || v2 > 7)
 	{
-		lwasm_register_error(as, l, "Invalid bit number");
+		lwasm_register_error(as, l, E_BITNUMBER_INVALID);
 		v2 = 0;
 	}
 	l -> pb = (l -> lint << 6) | (v1 << 3) | v2;
@@ -137,7 +137,7 @@
 		v2 = v1 - ((l -> dpval) << 8);
 		if (v2 > 0xFF || v2 < 0)
 		{
-			lwasm_register_error(as, l, "Byte overflow");
+			lwasm_register_error(as, l, E_BYTE_OVERFLOW);
 			return;
 		}
 	}
--- a/lwasm/insn_gen.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_gen.c	Mon Aug 05 21:27:09 2019 -0600
@@ -27,46 +27,50 @@
 #include "lwasm.h"
 #include "instab.h"
 
-extern void insn_indexed_parse_aux(asmstate_t *as, line_t *l, char **p);
-extern void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force, int elen);
-extern void insn_indexed_emit_aux(asmstate_t *as, line_t *l);
+void insn_indexed_parse_aux(asmstate_t *as, line_t *l, char **p);
+void insn_indexed_resolve_aux(asmstate_t *as, line_t *l, int force, int elen);
+void insn_indexed_emit_aux(asmstate_t *as, line_t *l);
 
-extern void insn_parse_indexed_aux(asmstate_t *as, line_t *l, char **p);
-extern void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen);
+void insn_parse_indexed_aux(asmstate_t *as, line_t *l, char **p);
+void insn_resolve_indexed_aux(asmstate_t *as, line_t *l, int force, int elen);
 
 // "extra" is required due to the way OIM, EIM, TIM, and AIM work
 void insn_parse_gen_aux(asmstate_t *as, line_t *l, char **p, int elen)
 {
-	const char *optr2;
+	char *optr2;
 	int v1, tv;
 	lw_expr_t s;
-
+	
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 
-	optr2 = *p;
-	while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++
-		/* do nothing */ ;
-
-	if (*optr2 == ',' || **p == '[')
+	/* this is the easy case - start it [ or , means indexed */
+	if (**p == ',' || **p == '[')
 	{
+indexed:
 		l -> lint = -1;
-		l -> lint2 = 1;
+		l -> lint2  = 1;
 		insn_parse_indexed_aux(as, l, p);
 		l -> minlen = OPLEN(instab[l -> insn].ops[1]) + 1 + elen;
 		l -> maxlen = OPLEN(instab[l -> insn].ops[1]) + 3 + elen;
 		goto out;
 	}
 
+	/* we have to parse the first expression to find if we have a comma after it */
+	optr2 = *p;
 	if (**p == '<')
 	{
 		(*p)++;
 		l -> lint2 = 0;
+		if (**p == '<')
+		{
+			*p = optr2;
+			goto indexed;
+		}
 	}
-
 	// for compatibility with asxxxx
 	// * followed by a digit, alpha, or _, or ., or ?, or another * is "f8"
 	else if (**p == '*')
@@ -87,18 +91,27 @@
 	{
 		l -> lint2 = -1;
 	}
-
-	l -> minlen = OPLEN(instab[l -> insn].ops[0]) + 1 + elen;
-	l -> maxlen = OPLEN(instab[l -> insn].ops[2]) + 2 + elen;
+	lwasm_skip_to_next_token(l, p);
+	
 	s = lwasm_parse_expr(as, p);
+	
+	if (**p == ',')
+	{
+		/* we have an indexed mode here - reset and transfer control to indexing mode */
+		lw_expr_destroy(s);
+		*p = optr2;
+		goto indexed;
+	}
 	if (!s)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
 	lwasm_save_expr(l, 0, s);
 
+	l -> minlen = OPLEN(instab[l -> insn].ops[0]) + 1 + elen;
+	l -> maxlen = OPLEN(instab[l -> insn].ops[2]) + 2 + elen;
 	if (as -> output_format == OUTPUT_OBJ && l -> lint2 == -1)
 	{
 		l -> lint2 = 2;
@@ -111,6 +124,8 @@
 	// if we have a constant now, figure out dp vs nondp
 	if (lw_expr_istype(s, lw_expr_type_int))
 	{
+		if (s -> value > 0xffff) lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+
 		v1 = lw_expr_intval(s);
 		if (((v1 >> 8) & 0xff) == (l -> dpval & 0xff))
 		{
@@ -165,7 +180,10 @@
 		}
 		else if (l -> lint2 == 1 && l -> lint != -1)
 		{
-			l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen;
+			if (l -> lint == 3)
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + 1 + elen;
+			else
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen;
 		}
 	}
 }
@@ -251,7 +269,10 @@
 		}
 		else if (l -> lint2 == 1 && l -> lint != -1)
 		{
-			l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen;
+			if (l -> lint == 3)
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + 1 + elen;
+			else
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1 + elen;
 		}
 	}
 }
@@ -268,6 +289,27 @@
 	
 	if (l -> lint2 == 1)
 	{
+		if (l -> lint == 3)
+		{
+			int offs;
+			if (lw_expr_istype(e, lw_expr_type_int))
+			{
+				offs = lw_expr_intval(e);
+				if ((offs >= -16 && offs <= 15) || offs >= 0xFFF0)
+				{
+					l -> pb |= offs & 0x1f;
+					l -> lint = 0;
+				}
+				else
+				{
+					lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+				}
+			}
+			else
+			{
+				lwasm_register_error(as, l, E_EXPRESSION_NOT_RESOLVED);
+			}
+		}
 		lwasm_emit(l, l -> pb);
 		if (l -> lint > 0)
 		{
@@ -276,17 +318,60 @@
 			if (l -> lint == 1)
 			{
 				if (i < -128 || i > 127)
-					lwasm_register_error(as, l, "Byte overflow");
+					lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+			}
+			else if (l -> lint == 2 && lw_expr_istype(e, lw_expr_type_int) && CURPRAGMA(l, PRAGMA_OPERANDSIZE))
+			{
+				// note that W relative and extended indirect must be 16 bits
+				if (l -> pb != 0xAF && l -> pb != 0xB0 && l -> pb != 0x9f)
+				{
+					if ((i >= -128 && i <= 127) || i >= 0xFF80)
+					{
+						lwasm_register_error(as, l, W_OPERAND_SIZE);
+
+					}
+				}
 			}
 			lwasm_emitexpr(l, e, l -> lint);
 		}
+
+		l -> cycle_adj = lwasm_cycle_calc_ind(l);
 		return;
 	}
 	
 	if (l -> lint2 == 2)
+	{
 		lwasm_emitexpr(l, e, 2);
+
+		if (CURPRAGMA(l, PRAGMA_OPERANDSIZE))
+		{
+			if (instab[l -> insn].ops[2] == 0xbd || instab[l -> insn].ops[2] == 0x7e)
+			{
+				// check if bsr or bra could be used instead
+				lw_expr_t e1, e2;
+				int offs;
+				e2 = lw_expr_build(lw_expr_type_special, lwasm_expr_linelen, l);
+				e1 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, e, e2);
+				lw_expr_destroy(e2);
+				e2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_minus, e1, l -> addr);
+				lw_expr_destroy(e1);
+				lwasm_reduce_expr(as, e2);
+				if (lw_expr_istype(e2, lw_expr_type_int))
+				{
+					offs = lw_expr_intval(e2);
+					if (offs >= -128 && offs <= 127)
+					{
+						lwasm_register_error(as, l, W_OPERAND_SIZE);
+					}
+				}
+				lw_expr_destroy(e2);
+			}
+		}
+	}
 	else
+	{
 		lwasm_emitexpr(l, e, 1);
+	}
 }
 
 // the various insn_gen? functions have an immediate mode of ? bits
@@ -294,7 +379,7 @@
 {
 	if (**p == '#')
 	{
-		lwasm_register_error(as, l, "Immediate mode not allowed");
+		lwasm_register_error(as, l, E_IMMEDIATE_INVALID);
 		return;
 	}
 	
@@ -318,15 +403,18 @@
 
 PARSEFUNC(insn_parse_gen8)
 {
+	l -> genmode = 8;
 	if (**p == '#')
 	{
 		lw_expr_t e;
 		
 		(*p)++;
+		as -> exprwidth = 8;
 		e = lwasm_parse_expr(as, p);
+		as -> exprwidth = 16;
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		l -> len = OPLEN(instab[l -> insn].ops[3]) + 1;
@@ -349,7 +437,10 @@
 		}
 		else if (l -> lint2 == 1 && l -> lint != -1)
 		{
-			l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
+			if (l -> lint == 3)
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + 1;
+			else
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
 		}
 	}
 }
@@ -369,6 +460,16 @@
 	{
 		lw_expr_t e;
 		e = lwasm_fetch_expr(l, 0);
+		if (lw_expr_istype(e, lw_expr_type_int))
+		{
+			int i;
+			i = lw_expr_intval(e);
+			if (i < -128 || i > 255)
+			{
+				lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+			}
+		}
+
 		lwasm_emitop(l, instab[l -> insn].ops[3]);
 		lwasm_emitexpr(l, e, 1);
 		return;
@@ -379,6 +480,7 @@
 
 PARSEFUNC(insn_parse_gen16)
 {
+	l -> genmode = 16;
 	if (**p == '#')
 	{
 		lw_expr_t e;
@@ -387,7 +489,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		l -> len = OPLEN(instab[l -> insn].ops[3]) + 2;
@@ -410,7 +512,10 @@
 		}
 		else if (l -> lint2 == 1 && l -> lint != -1)
 		{
-			l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
+			if (l -> lint == 3)
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + 1;
+			else
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
 		}
 	}
 }
@@ -440,6 +545,7 @@
 
 PARSEFUNC(insn_parse_gen32)
 {
+	l -> genmode = 32;
 	if (**p == '#')
 	{
 		lw_expr_t e;
@@ -448,7 +554,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		l -> len = OPLEN(instab[l -> insn].ops[3]) + 4;
@@ -471,7 +577,10 @@
 		}
 		else if (l -> lint2 == 1 && l -> lint != -1)
 		{
-			l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
+			if (l -> lint == 3)
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + 1;
+			else
+				l -> len = OPLEN(instab[l -> insn].ops[1]) + l -> lint + 1;
 		}
 	}
 }
@@ -507,10 +616,12 @@
 	{
 		(*p)++;
 
+		as -> exprwidth = 8;
 		e = lwasm_parse_expr(as, p);
+		as -> exprwidth = 16;
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		l -> len = OPLEN(instab[l -> insn].ops[0]) + 1;
@@ -518,7 +629,7 @@
 	}
 	else
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 	}
 }
 
@@ -528,5 +639,14 @@
 	
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	e = lwasm_fetch_expr(l, 0);
+	if (lw_expr_istype(e, lw_expr_type_int))
+	{
+		int i;
+		i = lw_expr_intval(e);
+		if (i < -128 || i > 255)
+		{
+			lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+		}
+	}
 	lwasm_emitexpr(l, e, 1);
 }
--- a/lwasm/insn_indexed.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_indexed.c	Mon Aug 05 21:27:09 2019 -0600
@@ -38,184 +38,310 @@
 */
 void insn_parse_indexed_aux(asmstate_t *as, line_t *l, char **p)
 {
-	struct opvals { char *opstr; int pb; };
-	
-	static const char *regs = "X  Y  U  S  W  PCRPC ";
-	static const struct opvals simpleindex[] =
-	{
-		{",x", 0x84},		{",y", 0xa4},		{",u", 0xc4},		{",s", 0xe4},
-		{",x+", 0x80},		{",y+", 0xa0},		{",u+", 0xc0},		{",s+", 0xe0},
-		{",x++", 0x81},		{",y++", 0xa1},		{",u++", 0xc1},		{",s++", 0xe1},
-		{",-x", 0x82},		{",-y", 0xa2},		{",-u", 0xc2},		{",-s", 0xe2},
-		{",--x", 0x83},		{",--y", 0xa3},		{",--u", 0xc3},		{",--s", 0xe3},
-		{"a,x", 0x86},		{"a,y", 0xa6},		{"a,u", 0xc6},		{"a,s", 0xe6},
-		{"b,x", 0x85},		{"b,y", 0xa5},		{"b,u", 0xc5},		{"b,s", 0xe5},
-		{"e,x", 0x87},		{"e,y", 0xa7},		{"e,u", 0xc7},		{"e,s", 0xe7},
-		{"f,x",	0x8a},		{"f,y",	0xaa},		{"f,u", 0xca},		{"f,s", 0xea},
-		{"d,x", 0x8b},		{"d,y", 0xab},		{"d,u", 0xcb},		{"d,s", 0xed},
-		{"w,x", 0x8e},		{"w,y", 0xae},		{"w,u", 0xce},		{"w,s", 0xee},
-		{",w", 0x8f},							{",w++", 0xcf},		{",--w", 0xef},
-		
-		{"[,x]", 0x94},		{"[,y]", 0xb4},		{"[,u]", 0xd4},		{"[,s]", 0xf4},
-		{"[,x++]", 0x91},	{"[,y++]", 0xb1},	{"[,u++]", 0xd1},	{"[,s++]", 0xf1},
-		{"[,--x]", 0x93},	{"[,--y]", 0xb3},	{"[,--u]", 0xd3},	{"[,--s]", 0xf3},
-		{"[a,x]", 0x96},	{"[a,y]", 0xb6},	{"[a,u]", 0xd6},	{"[a,s]", 0xf6},
-		{"[b,x]", 0x95},	{"[b,y]", 0xb5},	{"[b,u]", 0xd5},	{"[b,s]", 0xf5},
-		{"[e,x]", 0x97},	{"[e,y]", 0xb7},	{"[e,u]", 0xd7},	{"[e,s]", 0xf7},
-		{"[f,x]", 0x9a},	{"[f,y]", 0xba},	{"[f,u]", 0xda},	{"[f,s]", 0xfa},
-		{"[d,x]", 0x9b},	{"[d,y]", 0xbb},	{"[d,u]", 0xdb},	{"[d,s]", 0xfd},
-		{"[w,x]", 0x9e},	{"[w,y]", 0xbe},	{"[w,u]", 0xde},	{"[w,s]", 0xfe},
-		{"[,w]", 0x90},							{"[,w++]", 0xd0},	{"[,--w]", 0xf0},
-		
-		{ "", -1 }
-	};
-
 	static const char *regs9 = "X  Y  U  S     PCRPC ";
-	static const struct opvals simpleindex9[] =
-	{
-		{",x", 0x84},		{",y", 0xa4},		{",u", 0xc4},		{",s", 0xe4},
-		{",x+", 0x80},		{",y+", 0xa0},		{",u+", 0xc0},		{",s+", 0xe0},
-		{",x++", 0x81},		{",y++", 0xa1},		{",u++", 0xc1},		{",s++", 0xe1},
-		{",-x", 0x82},		{",-y", 0xa2},		{",-u", 0xc2},		{",-s", 0xe2},
-		{",--x", 0x83},		{",--y", 0xa3},		{",--u", 0xc3},		{",--s", 0xe3},
-		{"a,x", 0x86},		{"a,y", 0xa6},		{"a,u", 0xc6},		{"a,s", 0xe6},
-		{"b,x", 0x85},		{"b,y", 0xa5},		{"b,u", 0xc5},		{"b,s", 0xe5},
-		{"d,x", 0x8b},		{"d,y", 0xab},		{"d,u", 0xcb},		{"d,s", 0xed},
-		
-		{"[,x]", 0x94},		{"[,y]", 0xb4},		{"[,u]", 0xd4},		{"[,s]", 0xf4},
-		{"[,x++]", 0x91},	{"[,y++]", 0xb1},	{"[,u++]", 0xd1},	{"[,s++]", 0xf1},
-		{"[,--x]", 0x93},	{"[,--y]", 0xb3},	{"[,--u]", 0xd3},	{"[,--s]", 0xf3},
-		{"[a,x]", 0x96},	{"[a,y]", 0xb6},	{"[a,u]", 0xd6},	{"[a,s]", 0xf6},
-		{"[b,x]", 0x95},	{"[b,y]", 0xb5},	{"[b,u]", 0xd5},	{"[b,s]", 0xf5},
-		{"[d,x]", 0x9b},	{"[d,y]", 0xbb},	{"[d,u]", 0xdb},	{"[d,s]", 0xfd},
-		
-		{ "", -1 }
-	};
-	char stbuf[25];
-	int i, j, rn;
+	static const char *regs  = "X  Y  U  S  W  PCRPC ";
+	int i, rn;
 	int indir = 0;
-	int f0 = 1;
-	const struct opvals *simples;
+	int f0 = 0;
 	const char *reglist;
 	lw_expr_t e;
-		
-	if (as -> target == TARGET_6809)
+	char *tstr;
+	
+
+	if (CURPRAGMA(l, PRAGMA_6809))
 	{
-		simples = simpleindex9;
 		reglist = regs9;
 	}
 	else
 	{
-		simples = simpleindex;
 		reglist = regs;
 	}
-	
-	// fetch out operand for lookup
-	for (i = 0; i < 24; i++)
-	{
-		if (*((*p) + i) && !isspace(*((*p) + i)))
-			stbuf[i] = *((*p) + i);
-		else
-			break;
-	}
-	stbuf[i] = '\0';
-	
-	// now look up operand in "simple" table
-	if (!*((*p) + i) || isspace(*((*p) + i)))
-	{
-		// do simple lookup
-		for (j = 0; simples[j].opstr[0]; j++)
-		{
-			if (!strcasecmp(stbuf, simples[j].opstr))
-				break;
-		}
-		if (simples[j].opstr[0])
-		{
-			l -> pb = simples[j].pb;
-			l -> lint = 0;
-			(*p) += i;
-			return;
-		}
-	}
-
-	// now do the "hard" ones
-
 	// is it indirect?
 	if (**p == '[')
 	{
 		indir = 1;
 		(*p)++;
 	}
-	
-	// look for a "," - all indexed modes have a "," except extended indir
-	rn = 0;
-	for (i = 0; (*p)[i] && !isspace((*p)[i]); i++)
+	lwasm_skip_to_next_token(l, p);
+	if (**p == ',')
 	{
-		if ((*p)[i] == ',')
+		int incdec = 0;
+		/* we have a pre-dec, post-inc, or no offset mode here */
+		(*p)++;
+		lwasm_skip_to_next_token(l, p);
+		if (**p == '-')
 		{
+			incdec = -1;
+			(*p)++;
+			if (**p == '-')
+			{
+				incdec = -2;
+				(*p)++;
+			}
+			lwasm_skip_to_next_token(l, p);
+		}
+		/* allowed registers: X, Y, U, S, or W (6309) */
+		switch (**p)
+		{
+		case 'x':
+		case 'X':
+			rn = 0;
+			break;
+		
+		case 'y':
+		case 'Y':
 			rn = 1;
 			break;
+			
+		case 'u':
+		case 'U':
+			rn = 2;
+			break;
+			
+		case 's':
+		case 'S':
+			rn = 3;
+			break;
+			
+		case 'w':
+		case 'W':
+			if (CURPRAGMA(l, PRAGMA_6809))
+			{
+				lwasm_register_error(as, l, E_OPERAND_BAD);
+				return;
+			}
+			rn = 4;
+			break;
+			
+		default:
+			lwasm_register_error(as, l, E_OPERAND_BAD);
+			return;
+		}
+		(*p)++;
+		lwasm_skip_to_next_token(l, p);
+		if (**p == '+')
+		{
+			if (incdec != 0)
+			{
+				lwasm_register_error(as, l, E_OPERAND_BAD);
+				return;
+			}
+			incdec = 1;
+			(*p)++;
+			if (**p == '+')
+			{
+				incdec = 2;
+				(*p)++;
+			}
+			lwasm_skip_to_next_token(l, p);
+		}
+		if (indir)
+		{
+			if (**p != ']')
+			{
+				lwasm_register_error(as, l, E_OPERAND_BAD);
+				return;
+			}
+			(*p)++;
+		}
+		if (indir || rn == 4)
+		{
+			if (incdec == 1 || incdec == -1)
+			{
+				lwasm_register_error(as, l, E_OPERAND_BAD);
+				return;
+			}
+		}
+		if (rn == 4)
+		{
+			if (indir)
+			{
+				if (incdec == 0)
+					i = 0x90;
+				else if (incdec == -2)
+					i = 0xF0;
+				else
+					i = 0xD0;
+			}
+			else
+			{
+				if (incdec == 0)
+					i = 0x8F;
+				else if (incdec == -2)
+					i = 0xEF;
+				else
+					i = 0xCF;
+			}
+		}
+		else
+		{
+			switch (incdec)
+			{
+			case 0:
+				i = 0x84;
+				break;
+			case 1:
+				i = 0x80;
+				break;
+			case 2:
+				i = 0x81;
+				break;
+			case -1:
+				i = 0x82;
+				break;
+			case -2:
+				i = 0x83;
+				break;
+			}
+			i = (rn << 5) | i | (indir << 4);
+		}
+		l -> pb = i;
+		l -> lint = 0;
+		return;
+	}
+	i = toupper(**p);
+	if (
+			(i == 'A' || i == 'B' || i == 'D') ||
+			(!CURPRAGMA(l, PRAGMA_6809) && (i == 'E' || i == 'F' || i == 'W'))
+	   )
+	{
+		tstr = *p + 1;
+		lwasm_skip_to_next_token(l, &tstr);
+		if (*tstr == ',')
+		{
+			*p = tstr + 1;
+			lwasm_skip_to_next_token(l, p);
+			switch (**p)
+			{
+			case 'x':
+			case 'X':
+				rn = 0;
+				break;
+		
+			case 'y':
+			case 'Y':
+				rn = 1;
+				break;
+			
+			case 'u':
+			case 'U':
+				rn = 2;
+				break;
+			
+			case 's':
+			case 'S':
+				rn = 3;
+				break;
+			
+			default:
+				lwasm_register_error(as, l, E_OPERAND_BAD);
+				return;
+			}
+			(*p)++;
+			lwasm_skip_to_next_token(l, p);
+			if (indir)
+			{
+				if (**p != ']')
+				{
+					lwasm_register_error(as, l, E_OPERAND_BAD);
+					return;
+				}
+				(*p)++;
+			}
+			
+			switch (i)
+			{
+			case 'A':
+				i = 0x86;
+				break;
+			
+			case 'B':
+				i = 0x85;
+				break;
+			
+			case 'D':
+				i = 0x8B;
+				break;
+			
+			case 'E':
+				i = 0x87;
+				break;
+			
+			case 'F':
+				i = 0x8A;
+				break;
+			
+			case 'W':
+				i = 0x8E;
+				break;
+			}
+			l -> pb = i | (indir << 4) | (rn << 5);
+			l -> lint = 0;
+			return;
 		}
 	}
-
-	// if no "," and indirect, do extended indir
-	if (!rn && indir)
-	{
-		// eat the extended addressing indicator if present
-		if (**p == '>')
-			(*p)++;
-		// extended indir
-		l -> pb = 0x9f;
-		e = lwasm_parse_expr(as, p);
-		if (!e || **p != ']')
-		{
-			lwasm_register_error(as, l, "Bad operand");
-			return;
-		}
-		lwasm_save_expr(l, 0, e);
-		
-		(*p)++;
-		l -> lint = 2;
-		return;
-	}
-
+	
+	/* we have the "expression" types now */
 	if (**p == '<')
 	{
 		l -> lint = 1;
 		(*p)++;
+		if (**p == '<')
+		{
+			l -> lint = 3;
+			(*p)++;
+			if (indir)
+			{
+				lwasm_register_error(as, l, E_ILL5);
+				return;
+			}
+		}
 	}
 	else if (**p == '>')
 	{
 		l -> lint = 2;
 		(*p)++;
 	}
-
-	if (**p == '0' && *((*p)+1) == ',')
+	lwasm_skip_to_next_token(l, p);
+	if (**p == '0')
 	{
-		f0 = 1;
+		tstr = *p + 1;
+		lwasm_skip_to_next_token(l, &tstr);
+		if (*tstr == ',')
+		{
+			f0 = 1;
+		}
 	}
-	
+
 	// now we have to evaluate the expression
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 0, e);
-
-	// now look for a comma; if not present, explode
-	if (*(*p)++ != ',')
+	
+	if (**p != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		/* if no comma, we have extended indirect */
+		if (l -> lint == 1 || **p != ']')
+		{
+			lwasm_register_error(as, l, E_OPERAND_BAD);
+			return;
+		}
+		(*p)++;
+		l -> lint = 2;
+		l -> pb = 0x9F;
 		return;
 	}
-	
+	(*p)++;
+	lwasm_skip_to_next_token(l, p);
 	// now get the register
 	rn = lwasm_lookupreg3(reglist, p);
 	if (rn < 0)
 	{
-		lwasm_register_error(as, l, "Bad register");
+		lwasm_register_error(as, l, E_REGISTER_BAD);
 		return;
 	}
 	
@@ -223,7 +349,7 @@
 	{
 		if (**p != ']')
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		else
@@ -243,6 +369,10 @@
 			l -> pb = 0x89 | (rn << 5) | (indir ? 0x10 : 0);
 			return;
 		}
+		else if (l -> lint == 3)
+		{
+			l -> pb = (rn << 5);
+		}
 	}
 
 	// nnnn,W is only 16 bit (or 0 bit)
@@ -250,7 +380,12 @@
 	{
 		if (l -> lint == 1)
 		{
-			lwasm_register_error(as, l, "n,W cannot be 8 bit");
+			lwasm_register_error(as, l, E_NW_8);
+			return;
+		}
+		else if (l -> lint == 3)
+		{
+			lwasm_register_error(as, l, E_ILL5);
 			return;
 		}
 
@@ -293,11 +428,16 @@
 			l -> pb = indir ? 0x9C : 0x8C;
 			return;
 		}
-		if (l -> lint == 2)
+		else if (l -> lint == 2)
 		{
 			l -> pb = indir ? 0x9D : 0x8D;
 			return;
 		}
+		else if (l -> lint == 3)
+		{
+			lwasm_register_error(as, l, E_ILL5);
+			return;
+		}
 	}
 	
 	if (rn == 6)
@@ -307,14 +447,20 @@
 			l -> pb = indir ? 0x9C : 0x8C;
 			return;
 		}
-		if (l -> lint == 2)
+		else if (l -> lint == 2)
 		{
 			l -> pb = indir ? 0x9D : 0x8D;
 			return;
 		}
+		else if (l -> lint == 3)
+		{
+			lwasm_register_error(as, l, E_ILL5);
+			return;
+		}
 	}
 
-	l -> pb = (indir * 0x80) | rn | (f0 * 0x40);
+	if (l -> lint != 3)
+		l -> pb = (indir * 0x80) | rn | (f0 * 0x40);
 }
 
 PARSEFUNC(insn_parse_indexed)
@@ -324,7 +470,10 @@
 
 	if (l -> lint != -1)
 	{
-		l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
+		if (l -> lint == 3)
+			l -> len = OPLEN(instab[l -> insn].ops[0]) + 1;
+		else
+			l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
 	}
 }
 
@@ -455,6 +604,38 @@
 				return;
 			}
 		}
+		else
+		{
+			if ((l -> pb & 0x07) == 5 || (l -> pb & 0x07) == 6)
+			{
+				// NOTE: this will break in some particularly obscure corner cases
+				// which are not likely to show up in normal code. Notably, if, for
+				// some reason, the target gets *farther* away if shorter addressing
+				// modes are chosen, which should only happen if the symbol is before
+				// the instruction in the source file and there is some sort of ORG
+				// statement or similar in between which forces the address of this
+				// instruction, and the differences happen to cross the 8 bit boundary.
+				// For this reason, we use a heuristic and allow a margin on the 8
+				// bit boundary conditions.
+				v = as -> pretendmax;
+				as -> pretendmax = 1;
+				lwasm_reduce_expr(as, e2);
+				as -> pretendmax = v;
+				if (lw_expr_istype(e2, lw_expr_type_int))
+				{
+					v = lw_expr_intval(e2);
+					// Actual range is -128 <= offset <= 127; we're allowing a fudge
+					// factor of 25 or so bytes so that we're less likely to accidentally
+					// cross into the 16 bit boundary in weird corner cases.
+					if (v >= -100 && v <= 100)
+					{
+						l -> lint = 1;
+						l -> pb = (l -> pb & 0x80) ? 0x9C : 0x8C;
+						return;
+					}
+				}
+			}
+		}
 		lw_expr_destroy(e2);
 	}
 		
@@ -462,7 +643,8 @@
 	{
 		// we know how big it is
 		v = lw_expr_intval(e);
-		if (v == 0 && !CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) && (l -> pb & 0x07) <= 4)
+			
+		if (v == 0 && !CURPRAGMA(l, PRAGMA_NOINDEX0TONONE) && (l -> pb & 0x07) <= 4 && ((l -> pb & 0x40) == 0))
 		{
 			if ((l -> pb & 0x07) < 4)
 			{
@@ -573,7 +755,10 @@
 	
 	if (l -> lint != -1 && l -> pb != -1)
 	{
-		l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
+		if (l -> lint == 3)
+			l -> len = OPLEN(instab[l -> insn].ops[0]) + 1;
+		else
+			l -> len = OPLEN(instab[l -> insn].ops[0]) + l -> lint + 1;
 	}
 }
 
@@ -588,12 +773,53 @@
 		i = lw_expr_intval(e);
 		if (i < -128 || i > 127)
 		{
-			lwasm_register_error(as, l, "Byte overflow");
+			lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+		}
+	}
+	
+	// exclude expr,W since that can only be 16 bits
+	if (l -> lint == 3)
+	{
+		int offs;
+		e = lwasm_fetch_expr(l, 0);
+		if (lw_expr_istype(e, lw_expr_type_int))
+		{
+			offs = lw_expr_intval(e);
+			if ((offs >= -16 && offs <= 15) || offs >= 0xFFF0)
+			{
+				l -> pb |= offs & 0x1f;
+				l -> lint = 0;
+			}
+			else
+			{
+				lwasm_register_error(as, l, E_BYTE_OVERFLOW);
+			}
+		}
+		else
+		{
+			lwasm_register_error(as, l, E_EXPRESSION_NOT_RESOLVED);
+		}
+	}
+	// note that extended indirect (post byte 0x9f) can only be 16 bits
+	else if (l -> lint == 2 && CURPRAGMA(l, PRAGMA_OPERANDSIZE) && (l -> pb != 0xAF && l -> pb != 0xB0 && l -> pb != 0x9f))
+	{
+		int offs;
+		e = lwasm_fetch_expr(l, 0);
+		if (lw_expr_istype(e, lw_expr_type_int))
+		{
+			offs = lw_expr_intval(e);
+			if ((offs >= -128 && offs <= 127) || offs >= 0xFF80)
+			{
+				lwasm_register_error(as, l, W_OPERAND_SIZE);
+			}
 		}
 	}
 	
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	lwasm_emitop(l, l -> pb);
+
+	l -> cycle_adj = lwasm_cycle_calc_ind(l);
+
 	if (l -> lint > 0)
 	{
 		e = lwasm_fetch_expr(l, 0);
--- a/lwasm/insn_inh.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_inh.c	Mon Aug 05 21:27:09 2019 -0600
@@ -32,3 +32,64 @@
 {
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 }
+
+PARSEFUNC(insn_parse_inh6800)
+{
+	// there may be two operations here so check for both
+	l -> len = OPLEN(instab[l -> insn].ops[0]);
+	if (instab[l -> insn].ops[1] >= 0)
+		l -> len += OPLEN(instab[l -> insn].ops[1]);
+	skip_operand(p);
+}
+
+EMITFUNC(insn_emit_inh6800)
+{
+	// there may be two operations here so check for both
+	lwasm_emitop(l, instab[l -> insn].ops[0]);
+	if (instab[l -> insn].ops[1] >= 0)
+		lwasm_emitop(l, instab[l -> insn].ops[1]);
+	l -> cycle_base = instab[l -> insn].ops[3];
+}
+
+int negq_ops[] = { 0x10, 0x43, 0x10, 0x53, 0x10, 0x31, 0xc6, 0x10, 0x31, 0xc0 };
+#define negq_size (sizeof(negq_ops)/sizeof(int))
+
+PARSEFUNC(insn_parse_conv)
+{
+	int i;
+	l -> len = 0;
+	for (i = 0; i <= 2; i++)
+	{
+		if (instab[l -> insn].ops[i] >= 0)
+			l -> len += OPLEN(instab[l -> insn].ops[i]);
+	}
+
+	/* negq */
+	if (instab[l -> insn].ops[0] == -1)
+		l -> len = negq_size;
+	skip_operand(p);
+}
+
+EMITFUNC(insn_emit_conv)
+{
+	int i;
+	for (i = 0; i <= 2; i++)
+	{
+		if (instab[l -> insn].ops[i] >= 0)
+			lwasm_emitop(l, instab[l -> insn].ops[i]);
+	}
+
+	/* special case for negq */
+	if (instab[l -> insn].ops[0] == -1)
+	{
+		// 1043   (2)  comd
+		// 1053   (2)  comw
+		// 1031C6 (4)  adcr 0,w
+		// 1031C0 (4)  adcr 0,d
+
+		for (i = 0; i < negq_size; i++)
+			lwasm_emitop(l, negq_ops[i]);
+	}
+
+	l->cycle_base = instab[l -> insn].ops[3];
+}
\ No newline at end of file
--- a/lwasm/insn_logicmem.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_logicmem.c	Mon Aug 05 21:27:09 2019 -0600
@@ -29,9 +29,9 @@
 #include "lwasm.h"
 #include "instab.h"
 
-extern void insn_parse_gen_aux(asmstate_t *as, line_t *l, char **optr, int elen);
-extern void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen);
-extern void insn_emit_gen_aux(asmstate_t *as, line_t *l, int extra);
+void insn_parse_gen_aux(asmstate_t *as, line_t *l, char **optr, int elen);
+void insn_resolve_gen_aux(asmstate_t *as, line_t *l, int force, int elen);
+void insn_emit_gen_aux(asmstate_t *as, line_t *l, int extra);
 
 // for aim, oim, eim, tim
 PARSEFUNC(insn_parse_logicmem)
@@ -45,19 +45,20 @@
 	s = lwasm_parse_expr(as, p);
 	if (!s)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
 	lwasm_save_expr(l, 100, s);
+	lwasm_skip_to_next_token(l, p);
 	if (**p != ',' && **p != ';')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
 	(*p)++;
-
+	lwasm_skip_to_next_token(l, p);
 	// now we have a general addressing mode - call for it
 	insn_parse_gen_aux(as, l, p, 1);
 }
@@ -78,7 +79,7 @@
 	e = lwasm_fetch_expr(l, 100);
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
-		lwasm_register_error(as, l, "Immediate byte must be fully resolved");
+		lwasm_register_error(as, l, E_IMMEDIATE_UNRESOLVED);
 		return;
 	}
 	
@@ -86,7 +87,7 @@
 /*	if (v < -128 || v > 255)
 	{
 		fprintf(stderr, "BYTE: %d\n", v);
-		lwasm_register_error(as, l, "Byte overflow");
+		lwasm_register_error(as, l, E_BYTE_OVERFLOW);
 		return;
 	}
 */	
--- a/lwasm/insn_rel.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_rel.c	Mon Aug 05 21:27:09 2019 -0600
@@ -25,6 +25,7 @@
 #include <ctype.h>
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 
 #include <lw_expr.h>
 
@@ -47,7 +48,7 @@
 */
 PARSEFUNC(insn_parse_relgen)
 {
-	lw_expr_t t, e1, e2;
+	lw_expr_t t = NULL, e1, e2;
 	
 	l -> lint = -1;
 	l -> maxlen = OPLEN(instab[l -> insn].ops[3]) + 2;
@@ -76,11 +77,73 @@
 	if (**p == '#')
 		(*p)++;
 
-	t = lwasm_parse_expr(as, p);
+	if (CURPRAGMA(l, PRAGMA_QRTS))
+	{
+		// handle ?RTS conditional return
+		if (**p == '?')
+		{
+			if (strncasecmp(*p, "?RTS", 4) == 0)
+			{
+				(*p) += 4;
+
+				line_t *cl = l;
+				for (cl = cl->prev; cl; cl = cl->prev)
+				{
+					if (cl->insn == -1)
+						continue;
+
+					if (l->addr->value - cl->addr->value > 128)
+					{
+						cl = NULL;
+						break;
+					}
+
+					if (cl->conditional_return)
+						break;
+
+					if (instab[cl->insn].ops[0] == 0x39)
+						break;
+				}
+
+				if (cl)
+				{
+					l->lint = -1;
+					if (cl->conditional_return)
+					{
+						e2 = lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, cl);
+						e1 = lw_expr_build(lw_expr_type_int, 2);
+						t = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, e1, e2);
+					}
+					else
+					{
+						t = lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, cl);
+					}
+				}
+				else
+				{
+					l->conditional_return = 1;
+
+					// t = * + 1
+
+					e2 = lw_expr_build(lw_expr_type_special, lwasm_expr_lineaddr, l);
+					e1 = lw_expr_build(lw_expr_type_int, 1);
+					t = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, e1, e2);
+
+					lw_expr_destroy(e1);
+					lw_expr_destroy(e2);
+				}
+			}
+		}
+	}
+	
+	if (!t)
+	{
+		t = lwasm_parse_expr(as, p);
+	}
 
 	if (!t)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 
@@ -88,6 +151,7 @@
 	if (l -> lint == 8)
 	{
 		l -> len = OPLEN(instab[l -> insn].ops[2]) + 1;
+		if (l->conditional_return) l->len++;
 	}
 	else if (l -> lint == 16)
 	{
@@ -222,24 +286,41 @@
 	{
 		if (!lw_expr_istype(e, lw_expr_type_int))
 		{
-			lwasm_register_error(as, l, "Illegal non-constant expression");
+			lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 			return;
 		}
 	
 		offs = lw_expr_intval(e);
 		if (l -> lint == 8 && (offs < -128 || offs > 127))
 		{
-			lwasm_register_error(as, l, "Byte overflow");
+			lwasm_register_error(as, l, E_BYTE_OVERFLOW);
 			return;
 		}
-	
 
-		lwasm_emitop(l, instab[l -> insn].ops[2]);
-		lwasm_emit(l, offs);
+		if (l->conditional_return)
+		{
+			lwasm_emitop(l, instab[l->insn].ops[2] ^ 1);	/* flip branch, add RTS */
+			lwasm_emit(l, 1);
+			lwasm_emit(l, 0x39);
+			l->cycle_adj = 3;
+		}
+		else
+		{
+			lwasm_emitop(l, instab[l->insn].ops[2]);
+			lwasm_emit(l, offs);
+		}
 	}
 	else
 	{
 		lwasm_emitop(l, instab[l -> insn].ops[3]);
 		lwasm_emitexpr(l, e, 2);
+		if (CURPRAGMA(l, PRAGMA_OPERANDSIZE) && lw_expr_istype(e, lw_expr_type_int))
+		{
+			offs = lw_expr_intval(e);
+			if (offs >= -128 && offs <= 127)
+			{
+				lwasm_register_error(as, l, W_OPERAND_SIZE);
+			}
+		}
 	}
 }
--- a/lwasm/insn_rlist.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_rlist.c	Mon Aug 05 21:27:09 2019 -0600
@@ -33,20 +33,41 @@
 	int rn;
 	static const char *regs = "CCA B DPX Y U PCD S ";
 
-	while (**p && !isspace(**p))
+	while (**p && !isspace(**p) && **p != ';' && **p != '*')
 	{
 		rn = lwasm_lookupreg2(regs, p);
 		if (rn < 0)
 		{
-			lwasm_register_error(as, l, "Bad register '%s'", *p);
+			lwasm_register_error2(as, l, E_REGISTER_BAD, "'%s'", *p);
 			return;
 		}
-		if (**p && **p != ',' && !isspace(**p))
+		lwasm_skip_to_next_token(l, p);
+		if (**p && **p != ',' && !isspace(**p) && **p != ';' && **p != '*')
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 		}
 		if (**p == ',')
+		{
 			(*p)++;
+			lwasm_skip_to_next_token(l, p);
+		}
+		if ((instab[l -> insn].ops[0]) & 2)
+		{
+			// pshu/pulu
+			if (rn == 6)
+			{
+				lwasm_register_error2(as, l, E_REGISTER_BAD, "'%s'", "u");
+				return;
+			}
+		}
+		else
+		{
+			if (rn == 9)
+			{
+				lwasm_register_error2(as, l, E_REGISTER_BAD, "'%s'", "s");
+				return;
+			}
+		}
 		if (rn == 8)
 			rn = 6;
 		else if (rn == 9)
@@ -55,6 +76,8 @@
 			rn = 1 << rn;
 		rb |= rn;
 	}
+	if (rb == 0)
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 	l -> len = OPLEN(instab[l -> insn].ops[0]) + 1;
 	l -> pb = rb;
 }
@@ -63,4 +86,6 @@
 {
 	lwasm_emitop(l, instab[l -> insn].ops[0]);
 	lwasm_emit(l, l -> pb);
+
+	l -> cycle_adj = lwasm_cycle_calc_rlist(l);
 }
--- a/lwasm/insn_rtor.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_rtor.c	Mon Aug 05 21:27:09 2019 -0600
@@ -34,18 +34,20 @@
 	// D,X,Y,U,S,PC,W,V
 	// A,B,CC,DP,0,0,E,F
 
-	r0 = lwasm_lookupreg2((as -> target == TARGET_6309) ? regs : regs9, p);
+	r0 = lwasm_lookupreg2(!CURPRAGMA(l, PRAGMA_6809) ? regs : regs9, p);
+	lwasm_skip_to_next_token(l, p);
 	if (r0 < 0 || *(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		r0 = r1 = 0;
 	}
 	else
 	{
-		r1 = lwasm_lookupreg2((as -> target == TARGET_6309) ? regs : regs9, p);
+		lwasm_skip_to_next_token(l, p);
+		r1 = lwasm_lookupreg2(!CURPRAGMA(l, PRAGMA_6809) ? regs : regs9, p);
 		if (r1 < 0)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			r0 = r1 = 0;
 		}
 	}
--- a/lwasm/insn_tfm.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/insn_tfm.c	Mon Aug 05 21:27:09 2019 -0600
@@ -34,7 +34,7 @@
 	c = strchr(reglist, toupper(*(*p)++));
 	if (!c)
 	{
-		lwasm_register_error(as, l, "Unknown operation");
+		lwasm_register_error(as, l, E_REGISTER_BAD);
 		return;
 	}
 	r0 = c - reglist;
@@ -48,15 +48,17 @@
 		(*p)++;
 		tfm = 2;
 	}
+	lwasm_skip_to_next_token(l, p);
 	if (*(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Unknown operation");
+		lwasm_register_error(as, l, E_UNKNOWN_OPERATION);
 		return;
 	}
+	lwasm_skip_to_next_token(l, p);
 	c = strchr(reglist, toupper(*(*p)++));
 	if (!c)
 	{
-		lwasm_register_error(as, l, "Unknown operation");
+		lwasm_register_error(as, l, E_REGISTER_BAD);
 		return;
 	}
 	r1 = c - reglist;
@@ -74,10 +76,16 @@
 	
 	if (**p && !isspace(**p))
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
-			
+	/* only D, X, Y, U, S are valid tfm registers */
+	if (r0 > 4 || r1 > 4)
+	{
+		if (r0 < r1) r0 = r1;
+		lwasm_register_error2(as, l, E_REGISTER_BAD, "'%c'", reglist[r0]);
+	}
+
 	// valid values of tfm here are:
 	// 1: r0+,r1 (2)
 	// 4: r0,r1+ (3)
@@ -102,7 +110,7 @@
 		break;
 
 	default:
-		lwasm_register_error(as, l, "Unknown operation");
+		lwasm_register_error(as, l, E_UNKNOWN_OPERATION);
 		return;
 	}
 	l -> pb = (r0 << 4) | r1;
@@ -125,17 +133,19 @@
 	// D,X,Y,U,S,PC,W,V
 	// A,B,CC,DP,0,0,E,F
 	r0 = lwasm_lookupreg2(regs, p);
+	lwasm_skip_to_next_token(l, p);
 	if (r0 < 0 || *(*p)++ != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		r0 = r1 = 0;
 	}
 	else
 	{
+		lwasm_skip_to_next_token(l, p);
 		r1 = lwasm_lookupreg2(regs, p);
 		if (r1 < 0)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			r0 = r1 = 0;
 		}
 	}
--- a/lwasm/instab.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/instab.c	Mon Aug 05 21:27:09 2019 -0600
@@ -21,94 +21,98 @@
 Contains the instruction table for assembling code
 */
 #include <stdlib.h>
-#define __instab_c_seen__
 #include "instab.h"
 
 // inherent
-extern PARSEFUNC(insn_parse_inh);
+PARSEFUNC(insn_parse_inh);
 #define insn_resolve_inh NULL
-extern EMITFUNC(insn_emit_inh);
+EMITFUNC(insn_emit_inh);
+
+// inherent 6800 mode
+PARSEFUNC(insn_parse_inh6800);
+#define insn_resolve_inh6800 NULL
+EMITFUNC(insn_emit_inh6800);
 
 // register to register
-extern PARSEFUNC(insn_parse_rtor);
+PARSEFUNC(insn_parse_rtor);
 #define insn_resolve_rtor NULL
-extern EMITFUNC(insn_emit_rtor);
+EMITFUNC(insn_emit_rtor);
 
 // TFM and variants
-extern PARSEFUNC(insn_parse_tfmrtor);
+PARSEFUNC(insn_parse_tfmrtor);
 #define insn_resolve_tfmrtor NULL
-extern EMITFUNC(insn_emit_tfmrtor);
-extern PARSEFUNC(insn_parse_tfm);
+EMITFUNC(insn_emit_tfmrtor);
+PARSEFUNC(insn_parse_tfm);
 #define insn_resolve_tfm NULL
-extern EMITFUNC(insn_emit_tfm);
+EMITFUNC(insn_emit_tfm);
 
 // register list
-extern PARSEFUNC(insn_parse_rlist);
+PARSEFUNC(insn_parse_rlist);
 #define insn_resolve_rlist NULL
-extern EMITFUNC(insn_emit_rlist);
+EMITFUNC(insn_emit_rlist);
 
 // indexed
-extern PARSEFUNC(insn_parse_indexed);
-extern RESOLVEFUNC(insn_resolve_indexed);
-extern EMITFUNC(insn_emit_indexed);
+PARSEFUNC(insn_parse_indexed);
+RESOLVEFUNC(insn_resolve_indexed);
+EMITFUNC(insn_emit_indexed);
 
 // generic 32 bit immediate
-extern PARSEFUNC(insn_parse_gen32);
-extern RESOLVEFUNC(insn_resolve_gen32);
-extern EMITFUNC(insn_emit_gen32);
+PARSEFUNC(insn_parse_gen32);
+RESOLVEFUNC(insn_resolve_gen32);
+EMITFUNC(insn_emit_gen32);
 
 // generic 16 bit immediate
-extern PARSEFUNC(insn_parse_gen16);
-extern RESOLVEFUNC(insn_resolve_gen16);
-extern EMITFUNC(insn_emit_gen16);
+PARSEFUNC(insn_parse_gen16);
+RESOLVEFUNC(insn_resolve_gen16);
+EMITFUNC(insn_emit_gen16);
 
 // generic 8 bit immediate
-extern PARSEFUNC(insn_parse_gen8);
-extern RESOLVEFUNC(insn_resolve_gen8);
-extern EMITFUNC(insn_emit_gen8);
+PARSEFUNC(insn_parse_gen8);
+RESOLVEFUNC(insn_resolve_gen8);
+EMITFUNC(insn_emit_gen8);
 
 // generic no immediate
-extern PARSEFUNC(insn_parse_gen0);
-extern RESOLVEFUNC(insn_resolve_gen0);
-extern EMITFUNC(insn_emit_gen0);
+PARSEFUNC(insn_parse_gen0);
+RESOLVEFUNC(insn_resolve_gen0);
+EMITFUNC(insn_emit_gen0);
 
 // logic memory
-extern PARSEFUNC(insn_parse_logicmem);
-extern RESOLVEFUNC(insn_resolve_logicmem);
-extern EMITFUNC(insn_emit_logicmem);
+PARSEFUNC(insn_parse_logicmem);
+RESOLVEFUNC(insn_resolve_logicmem);
+EMITFUNC(insn_emit_logicmem);
 
 // 8 bit immediate only
-extern PARSEFUNC(insn_parse_imm8);
+PARSEFUNC(insn_parse_imm8);
 #define insn_resolve_imm8 NULL
-extern EMITFUNC(insn_emit_imm8);
+EMITFUNC(insn_emit_imm8);
 
 // bit to bit ops
-extern PARSEFUNC(insn_parse_bitbit);
+PARSEFUNC(insn_parse_bitbit);
 #define insn_resolve_bitbit NULL
-extern EMITFUNC(insn_emit_bitbit);
+EMITFUNC(insn_emit_bitbit);
 
 // 8 bit relative
-extern PARSEFUNC(insn_parse_rel8);
+PARSEFUNC(insn_parse_rel8);
 #define insn_resolve_rel8 NULL
-extern EMITFUNC(insn_emit_rel8);
+EMITFUNC(insn_emit_rel8);
 
 // 16 bit relative
-extern PARSEFUNC(insn_parse_rel16);
+PARSEFUNC(insn_parse_rel16);
 #define insn_resolve_rel16 NULL
-extern EMITFUNC(insn_emit_rel16);
+EMITFUNC(insn_emit_rel16);
 
 // generic 8/16 bit relative
-extern PARSEFUNC(insn_parse_relgen);
-extern RESOLVEFUNC(insn_resolve_relgen);
-extern EMITFUNC(insn_emit_relgen);
+PARSEFUNC(insn_parse_relgen);
+RESOLVEFUNC(insn_resolve_relgen);
+EMITFUNC(insn_emit_relgen);
 
 // MACRO pseudo op
-extern PARSEFUNC(pseudo_parse_macro);
+PARSEFUNC(pseudo_parse_macro);
 #define pseudo_resolve_macro	NULL
 #define pseudo_emit_macro NULL
 
 // ENDM pseudo op
-extern PARSEFUNC(pseudo_parse_endm);
+PARSEFUNC(pseudo_parse_endm);
 #define pseudo_resolve_endm NULL
 #define pseudo_emit_endm NULL
 
@@ -116,220 +120,259 @@
 #define pseudo_resolve_noop NULL
 #define pseudo_emit_noop NULL
 
-extern PARSEFUNC(pseudo_parse_dts);
+PARSEFUNC(pseudo_parse_dts);
 #define pseudo_resolve_dts NULL
-extern EMITFUNC(pseudo_emit_dts);
+EMITFUNC(pseudo_emit_dts);
 
-extern PARSEFUNC(pseudo_parse_dtb);
+PARSEFUNC(pseudo_parse_dtb);
 #define pseudo_resolve_dtb NULL
-extern EMITFUNC(pseudo_emit_dtb);
+EMITFUNC(pseudo_emit_dtb);
 
-extern PARSEFUNC(pseudo_parse_end);
+PARSEFUNC(pseudo_parse_end);
 #define pseudo_resolve_end NULL
-extern EMITFUNC(pseudo_emit_end);
+EMITFUNC(pseudo_emit_end);
 
-extern PARSEFUNC(pseudo_parse_fcb);
+PARSEFUNC(pseudo_parse_fcb);
 #define pseudo_resolve_fcb NULL
-extern EMITFUNC(pseudo_emit_fcb);
+EMITFUNC(pseudo_emit_fcb);
 
-extern PARSEFUNC(pseudo_parse_fdb);
+PARSEFUNC(pseudo_parse_fdb);
 #define pseudo_resolve_fdb NULL
-extern EMITFUNC(pseudo_emit_fdb);
+EMITFUNC(pseudo_emit_fdb);
 
-extern PARSEFUNC(pseudo_parse_fdbs);
+PARSEFUNC(pseudo_parse_fdbs);
 #define pseudo_resolve_fdbs NULL
-extern EMITFUNC(pseudo_emit_fdbs);
+EMITFUNC(pseudo_emit_fdbs);
 
-extern PARSEFUNC(pseudo_parse_fqb);
+PARSEFUNC(pseudo_parse_fqb);
 #define pseudo_resolve_fqb NULL
-extern EMITFUNC(pseudo_emit_fqb);
+EMITFUNC(pseudo_emit_fqb);
 
-extern PARSEFUNC(pseudo_parse_fcc);
+PARSEFUNC(pseudo_parse_fcc);
 #define pseudo_resolve_fcc NULL
-extern EMITFUNC(pseudo_emit_fcc);
+EMITFUNC(pseudo_emit_fcc);
 
-extern PARSEFUNC(pseudo_parse_fcs);
+PARSEFUNC(pseudo_parse_fcs);
 #define pseudo_resolve_fcs NULL
-extern EMITFUNC(pseudo_emit_fcs);
+EMITFUNC(pseudo_emit_fcs);
 
-extern PARSEFUNC(pseudo_parse_fcn);
+PARSEFUNC(pseudo_parse_fcn);
 #define pseudo_resolve_fcn NULL
-extern EMITFUNC(pseudo_emit_fcn);
+EMITFUNC(pseudo_emit_fcn);
 
-extern PARSEFUNC(pseudo_parse_rmb);
-extern RESOLVEFUNC(pseudo_resolve_rmb);
-extern EMITFUNC(pseudo_emit_rmb);
+PARSEFUNC(pseudo_parse_rmb);
+RESOLVEFUNC(pseudo_resolve_rmb);
+EMITFUNC(pseudo_emit_rmb);
 
-extern PARSEFUNC(pseudo_parse_rmd);
-extern RESOLVEFUNC(pseudo_resolve_rmd);
-extern EMITFUNC(pseudo_emit_rmd);
+PARSEFUNC(pseudo_parse_rmd);
+RESOLVEFUNC(pseudo_resolve_rmd);
+EMITFUNC(pseudo_emit_rmd);
 
-extern PARSEFUNC(pseudo_parse_rmq);
-extern RESOLVEFUNC(pseudo_resolve_rmq);
-extern EMITFUNC(pseudo_emit_rmq);
+PARSEFUNC(pseudo_parse_rmq);
+RESOLVEFUNC(pseudo_resolve_rmq);
+EMITFUNC(pseudo_emit_rmq);
 
-extern PARSEFUNC(pseudo_parse_zmb);
-extern RESOLVEFUNC(pseudo_resolve_zmb);
-extern EMITFUNC(pseudo_emit_zmb);
+PARSEFUNC(pseudo_parse_zmb);
+RESOLVEFUNC(pseudo_resolve_zmb);
+EMITFUNC(pseudo_emit_zmb);
 
-extern PARSEFUNC(pseudo_parse_zmd);
-extern RESOLVEFUNC(pseudo_resolve_zmd);
-extern EMITFUNC(pseudo_emit_zmd);
+PARSEFUNC(pseudo_parse_zmd);
+RESOLVEFUNC(pseudo_resolve_zmd);
+EMITFUNC(pseudo_emit_zmd);
 
-extern PARSEFUNC(pseudo_parse_zmq);
-extern RESOLVEFUNC(pseudo_resolve_zmq);
-extern EMITFUNC(pseudo_emit_zmq);
+PARSEFUNC(pseudo_parse_zmq);
+RESOLVEFUNC(pseudo_resolve_zmq);
+EMITFUNC(pseudo_emit_zmq);
 
-extern PARSEFUNC(pseudo_parse_org);
+PARSEFUNC(pseudo_parse_org);
 #define pseudo_resolve_org NULL
 #define pseudo_emit_org NULL
 
-extern PARSEFUNC(pseudo_parse_equ);
+PARSEFUNC(pseudo_parse_reorg);
+#define pseudo_resolve_reorg NULL
+#define pseudo_emit_reorg NULL
+
+PARSEFUNC(pseudo_parse_equ);
 #define pseudo_resolve_equ NULL
 #define pseudo_emit_equ NULL
 
-extern PARSEFUNC(pseudo_parse_set);
+PARSEFUNC(pseudo_parse_set);
 #define pseudo_resolve_set NULL
 #define pseudo_emit_set NULL
 
-extern PARSEFUNC(pseudo_parse_setdp);
+PARSEFUNC(pseudo_parse_setdp);
 #define pseudo_resolve_setdp NULL
 #define pseudo_emit_setdp NULL
 
-extern PARSEFUNC(pseudo_parse_ifp1);
+PARSEFUNC(pseudo_parse_ifp1);
 #define pseudo_resolve_ifp1 NULL
 #define pseudo_emit_ifp1 NULL
 
-extern PARSEFUNC(pseudo_parse_ifp2);
+PARSEFUNC(pseudo_parse_ifp2);
 #define pseudo_resolve_ifp2 NULL
 #define pseudo_emit_ifp2 NULL
 
-extern PARSEFUNC(pseudo_parse_ifne);
+PARSEFUNC(pseudo_parse_ifne);
 #define pseudo_resolve_ifne NULL
 #define pseudo_emit_ifne NULL
 
-extern PARSEFUNC(pseudo_parse_ifeq);
+PARSEFUNC(pseudo_parse_ifeq);
 #define pseudo_resolve_ifeq NULL
 #define pseudo_emit_ifeq NULL
 
-extern PARSEFUNC(pseudo_parse_iflt);
+PARSEFUNC(pseudo_parse_iflt);
 #define pseudo_resolve_iflt NULL
 #define pseudo_emit_iflt NULL
 
-extern PARSEFUNC(pseudo_parse_ifle);
+PARSEFUNC(pseudo_parse_ifle);
 #define pseudo_resolve_ifle NULL
 #define pseudo_emit_ifle NULL
 
-extern PARSEFUNC(pseudo_parse_ifgt);
+PARSEFUNC(pseudo_parse_ifgt);
 #define pseudo_resolve_ifgt NULL
 #define pseudo_emit_ifgt NULL
 
-extern PARSEFUNC(pseudo_parse_ifge);
+PARSEFUNC(pseudo_parse_ifge);
 #define pseudo_resolve_ifge NULL
 #define pseudo_emit_ifge NULL
 
-extern PARSEFUNC(pseudo_parse_ifdef);
+PARSEFUNC(pseudo_parse_ifdef);
 #define pseudo_resolve_ifdef NULL
 #define pseudo_emit_ifdef NULL
 
-extern PARSEFUNC(pseudo_parse_ifndef);
+PARSEFUNC(pseudo_parse_ifndef);
 #define pseudo_resolve_ifndef NULL
 #define pseudo_emit_ifndef NULL
 
-extern PARSEFUNC(pseudo_parse_ifstr);
+PARSEFUNC(pseudo_parse_ifpragma);
+#define pseudo_resolve_ifpragma NULL
+#define pseudo_emit_ifpragma NULL
+
+PARSEFUNC(pseudo_parse_ifstr);
 #define pseudo_resolve_ifstr NULL
 #define pseudo_emit_ifstr NULL
 
-extern PARSEFUNC(pseudo_parse_endc);
+PARSEFUNC(pseudo_parse_endc);
 #define pseudo_resolve_endc NULL
 #define pseudo_emit_endc NULL
 
-extern PARSEFUNC(pseudo_parse_else);
+PARSEFUNC(pseudo_parse_else);
 #define pseudo_resolve_else NULL
 #define pseudo_emit_else NULL
 
-extern PARSEFUNC(pseudo_parse_pragma);
+PARSEFUNC(pseudo_parse_pragma);
 #define pseudo_resolve_pragma NULL
 #define pseudo_emit_pragma NULL
 
-extern PARSEFUNC(pseudo_parse_starpragma);
+PARSEFUNC(pseudo_parse_starpragma);
 #define pseudo_resolve_starpragma NULL
 #define pseudo_emit_starpragma NULL
 
-extern PARSEFUNC(pseudo_parse_starpragmapush);
+PARSEFUNC(pseudo_parse_starpragmapush);
 #define pseudo_resolve_starpragmapush NULL
 #define pseudo_emit_starpragmapush NULL
 
-extern PARSEFUNC(pseudo_parse_starpragmapop);
+PARSEFUNC(pseudo_parse_starpragmapop);
 #define pseudo_resolve_starpragmapop NULL
 #define pseudo_emit_starpragmapop NULL
 
-extern PARSEFUNC(pseudo_parse_section);
+PARSEFUNC(pseudo_parse_section);
 #define pseudo_resolve_section NULL
 #define pseudo_emit_section NULL
 
-extern PARSEFUNC(pseudo_parse_endsection);
+PARSEFUNC(pseudo_parse_endsection);
 #define pseudo_resolve_endsection NULL
 #define pseudo_emit_endsection NULL
 
-extern PARSEFUNC(pseudo_parse_error);
+PARSEFUNC(pseudo_parse_error);
 #define pseudo_resolve_error NULL
 #define pseudo_emit_error NULL
 
-extern PARSEFUNC(pseudo_parse_warning);
+PARSEFUNC(pseudo_parse_warning);
 #define pseudo_resolve_warning NULL
 #define pseudo_emit_warning NULL
 
-extern PARSEFUNC(pseudo_parse_os9);
+PARSEFUNC(pseudo_parse_os9);
 #define pseudo_resolve_os9 NULL
-extern EMITFUNC(pseudo_emit_os9);
+EMITFUNC(pseudo_emit_os9);
 
-extern PARSEFUNC(pseudo_parse_mod);
+PARSEFUNC(pseudo_parse_mod);
 #define pseudo_resolve_mod NULL
-extern EMITFUNC(pseudo_emit_mod);
+EMITFUNC(pseudo_emit_mod);
 
-extern PARSEFUNC(pseudo_parse_emod);
+PARSEFUNC(pseudo_parse_emod);
 #define pseudo_resolve_emod NULL
-extern EMITFUNC(pseudo_emit_emod);
+EMITFUNC(pseudo_emit_emod);
 
-extern PARSEFUNC(pseudo_parse_extdep);
+PARSEFUNC(pseudo_parse_extdep);
 #define pseudo_resolve_extdep NULL
 #define pseudo_emit_extdep NULL
 
-extern PARSEFUNC(pseudo_parse_extern);
+PARSEFUNC(pseudo_parse_extern);
 #define pseudo_resolve_extern NULL
 #define pseudo_emit_extern NULL
 
-extern PARSEFUNC(pseudo_parse_export);
+PARSEFUNC(pseudo_parse_export);
 #define pseudo_resolve_export NULL
 #define pseudo_emit_export NULL
 
-extern PARSEFUNC(pseudo_parse_includebin);
+PARSEFUNC(pseudo_parse_includebin);
 #define pseudo_resolve_includebin NULL
-extern EMITFUNC(pseudo_emit_includebin);
+EMITFUNC(pseudo_emit_includebin);
 
-extern PARSEFUNC(pseudo_parse_include);
+PARSEFUNC(pseudo_parse_include);
 #define pseudo_resolve_include NULL
 #define pseudo_emit_include NULL
 
-extern PARSEFUNC(pseudo_parse_align);
-extern RESOLVEFUNC(pseudo_resolve_align);
-extern EMITFUNC(pseudo_emit_align);
+PARSEFUNC(pseudo_parse_align);
+RESOLVEFUNC(pseudo_resolve_align);
+EMITFUNC(pseudo_emit_align);
 
-extern PARSEFUNC(pseudo_parse_fill);
-extern RESOLVEFUNC(pseudo_resolve_fill);
-extern EMITFUNC(pseudo_emit_fill);
+PARSEFUNC(pseudo_parse_fill);
+RESOLVEFUNC(pseudo_resolve_fill);
+EMITFUNC(pseudo_emit_fill);
 
-extern PARSEFUNC(pseudo_parse_struct);
+PARSEFUNC(pseudo_parse_struct);
 #define pseudo_resolve_struct NULL
 #define pseudo_emit_struct NULL
 
-extern PARSEFUNC(pseudo_parse_endstruct);
+PARSEFUNC(pseudo_parse_endstruct);
 #define pseudo_resolve_endstruct NULL
 #define pseudo_emit_endstruct NULL
 
+// convenience ops
+PARSEFUNC(insn_parse_conv);
+#define insn_resolve_conv NULL
+EMITFUNC(insn_emit_conv);
+
 instab_t instab[] =
 {
+	// 6809 convenience instructions
+	{ "asrd",		{	0x4756,	-1,		-1,		 4 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "clrd",		{	0x4f5f,	-1,		-1,		 4 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "comd",		{	0x4353,	-1,		-1,		 4 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "lsld",		{	0x5849,	-1,		-1,		 4 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "lsrd",		{	0x4456,	-1,		-1,		 4 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "negd",		{	0x4353,	0x83ff, 0xff,	 8 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+	{ "tstd",		{	0xed7e,	-1,		-1,		 6 },	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6809conv },
+
+	// 6309 convenience instructions
+	{ "asrq",		{	0x1047,	0x1056,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "clrq",		{	0x104f,	0x105f,	-1,		 4 	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "comq",		{	0x1043,	0x1053,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "lsle",		{	0x1030,	0xee,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "lslf",		{	0x1030,	0xff,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "lslq",		{	0x1030, 0x6610,	0x49,	 6	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "lsrq",		{	0x1044,	0x1056,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "nege",		{	0x1032,	0xce,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "negf",		{	0x1032,	0xcf,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "negw",		{	0x1032,	0xc6,	-1,		 4	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "negq",		{	-1,		-1,		-1,		12	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+	{ "tstq",		{	0x10ed,	0x7c,	-1,		 9	},	insn_parse_conv,		insn_resolve_conv,				insn_emit_conv,				lwasm_insn_is6309conv },
+
+	// emulator extensions
+	{ "break",		{ 0x113e,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_isemuext },
+	{ "log",		{ 0x103e,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_isemuext },
 
 	{ "abx",		{	0x3a,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
 	{ "adca",		{	0x99,	0xa9,	0xb9,	0x89},	insn_parse_gen8,		insn_resolve_gen8,				insn_emit_gen8,				lwasm_insn_normal},
@@ -433,6 +476,8 @@
 	{ "eorr",		{	0x1036,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				insn_emit_rtor,				lwasm_insn_is6309},
 	{ "exg",		{	0x1e,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				insn_emit_rtor,				lwasm_insn_normal},
 
+	{ "hcf",		{	0x14,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_is6809},
+
 	{ "inc",		{	0x0c,	0x6c,	0x7c,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				insn_emit_gen0,				lwasm_insn_normal},
 	{ "inca",		{	0x4c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
 	{ "incb",		{	0x5c,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
@@ -516,6 +561,8 @@
 	{ "pulu",		{	0x37,	-1,		-1,		-1	},	insn_parse_rlist,		insn_resolve_rlist,				insn_emit_rlist,				lwasm_insn_normal},
 	{ "puluw",		{	0x103b,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_is6309},
 	
+	{ "reset",		{	0x3e,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_is6809},
+	{ "rhf",		{	0x14,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_is6809},
 	{ "rol",		{	0x09,	0x69,	0x79,	-1	},	insn_parse_gen0,		insn_resolve_gen0,				insn_emit_gen0,				lwasm_insn_normal},
 	{ "rola",		{	0x49,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
 	{ "rolb",		{	0x59,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
@@ -553,7 +600,7 @@
 	{ "sube",		{	0x1190,	0x11a0,	0x11b0,	0x1180},insn_parse_gen8,		insn_resolve_gen8,				insn_emit_gen8,				lwasm_insn_is6309},
 	{ "subf",		{	0x11d0,	0x11e0,	0x11f0,	0x11c0},insn_parse_gen8,		insn_resolve_gen8,				insn_emit_gen8,				lwasm_insn_is6309},
 	{ "subr",		{	0x1032,	-1,		-1,		-1	},	insn_parse_rtor,		insn_resolve_rtor,				insn_emit_rtor,				lwasm_insn_is6309},
-	{ "subw",		{	0x1090,	0x10a0,	0x1090,	0x1080},insn_parse_gen16,		insn_resolve_gen16,				insn_emit_gen16,			lwasm_insn_is6309},
+	{ "subw",		{	0x1090,	0x10a0,	0x10b0,	0x1080},insn_parse_gen16,		insn_resolve_gen16,				insn_emit_gen16,			lwasm_insn_is6309},
 	{ "swi",		{	0x3f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
 	{ "swi2",		{	0x103f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
 	{ "swi3",		{	0x113f,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_normal},
@@ -589,6 +636,7 @@
 	{ "tstw",		{	0x105d,	-1,		-1,		-1	},	insn_parse_inh,			insn_resolve_inh,				insn_emit_inh,				lwasm_insn_is6309},
 
 	{ "org",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_org,		pseudo_resolve_org,				pseudo_emit_org,			lwasm_insn_normal},
+	{ "reorg",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_reorg,		pseudo_resolve_reorg,			pseudo_emit_reorg,			lwasm_insn_normal},
 	{ "equ",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_equ,		pseudo_resolve_equ,				pseudo_emit_equ,			lwasm_insn_setsym},
 	{ "=",			{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_equ,		pseudo_resolve_equ,				pseudo_emit_equ,			lwasm_insn_setsym},
 
@@ -604,6 +652,7 @@
 	{ "rmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_rmq,		pseudo_resolve_rmq,				pseudo_emit_rmq,			lwasm_insn_struct | lwasm_insn_setdata},
 
 	{ "zmb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmb,		pseudo_resolve_zmb,				pseudo_emit_zmb,			lwasm_insn_normal},
+	{ "bsz", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmb,		pseudo_resolve_zmb,				pseudo_emit_zmb,			lwasm_insn_normal},
 	{ "fzb", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmb,		pseudo_resolve_zmb,				pseudo_emit_zmb,			lwasm_insn_normal},
 	{ "zmd", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmd,		pseudo_resolve_zmd,				pseudo_emit_zmd,			lwasm_insn_normal},
 	{ "zmq", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_zmq,		pseudo_resolve_zmq,				pseudo_emit_zmq,			lwasm_insn_normal},
@@ -611,6 +660,7 @@
 	{ "fcc",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcc,		pseudo_resolve_fcc,				pseudo_emit_fcc,			lwasm_insn_normal},
 	{ "fcn",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcn,		pseudo_resolve_fcn,				pseudo_emit_fcn,			lwasm_insn_normal},
 	{ "fcs",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcs,		pseudo_resolve_fcs,				pseudo_emit_fcs,			lwasm_insn_normal},
+	{ "fcz",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcn,		pseudo_resolve_fcn,				pseudo_emit_fcn,			lwasm_insn_normal},
 
 	{ "fcb",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fcb,		pseudo_resolve_fcb,				pseudo_emit_fcb,			lwasm_insn_normal},
 	{ "fdb",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_fdb,		pseudo_resolve_fdb,				pseudo_emit_fdb,			lwasm_insn_normal},
@@ -620,6 +670,7 @@
 
 	{ "includebin", {	-1, 	-1, 	-1, 	-1},	pseudo_parse_includebin,pseudo_resolve_includebin,		pseudo_emit_includebin,		lwasm_insn_normal},
 	{ "include",	{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_include,	pseudo_resolve_include,			pseudo_emit_include,		lwasm_insn_normal},
+	{ "incl",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_include,	pseudo_resolve_include,			pseudo_emit_include,		lwasm_insn_normal},
 	{ "use",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_include,	pseudo_resolve_include,			pseudo_emit_include,		lwasm_insn_normal},
 	
 	{ "align", 		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_align,		pseudo_resolve_align,			pseudo_emit_align,			lwasm_insn_normal},
@@ -627,6 +678,7 @@
 
 	{ "error",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_error,		pseudo_resolve_error,			pseudo_emit_error,			lwasm_insn_normal},
 	{ "warning",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_warning,	pseudo_resolve_warning,			pseudo_emit_warning,		lwasm_insn_normal},
+	{ "msg",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_warning,	pseudo_resolve_warning,			pseudo_emit_warning,		lwasm_insn_normal},
 
 	// these are *dangerous*
 	{ "ifp1",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifp1,		pseudo_resolve_ifp1,			pseudo_emit_ifp1,			lwasm_insn_cond},
@@ -644,11 +696,14 @@
 	{ "else",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_else,		pseudo_resolve_else,			pseudo_emit_else,			lwasm_insn_cond},
 	{ "ifdef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifdef,		pseudo_resolve_ifdef,			pseudo_emit_ifdef,			lwasm_insn_cond},
 	{ "ifndef",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_ifndef,	pseudo_resolve_ifndef,			pseudo_emit_ifndef,			lwasm_insn_cond},
+	{ "ifpragma",	{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifpragma,	pseudo_resolve_ifpragma,		pseudo_emit_ifpragma,		lwasm_insn_cond},
+	{ "ifopt",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_ifpragma,	pseudo_resolve_ifpragma,		pseudo_emit_ifpragma,		lwasm_insn_cond},
 
 	// string operations, mostly useful in macros
 	{ "ifstr",		{	-1,		-1,		-1,		-1},	pseudo_parse_ifstr,		pseudo_resolve_ifstr,			pseudo_emit_ifstr,			lwasm_insn_cond},
 
 	{ "macro",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_macro,		pseudo_resolve_macro,			pseudo_emit_macro,			lwasm_insn_cond | lwasm_insn_setsym},
+	{ "macr",		{	-1, 	-1, 	-1, 	-1}, 	pseudo_parse_macro,		pseudo_resolve_macro,			pseudo_emit_macro,			lwasm_insn_cond | lwasm_insn_setsym},
 	{ "endm",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_endm,		pseudo_resolve_endm,			pseudo_emit_endm,			lwasm_insn_cond | lwasm_insn_setsym | lwasm_insn_endm},
 
 	{ "setdp", 		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_setdp,		pseudo_resolve_setdp,			pseudo_emit_setdp,			lwasm_insn_normal},
@@ -667,6 +722,7 @@
 
 	{ "pragma",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_pragma,	pseudo_resolve_pragma,			pseudo_emit_pragma,			lwasm_insn_normal},
 	{ "*pragma",	{	-1, 	-1, 	-1, 	-1},	pseudo_parse_starpragma,pseudo_resolve_starpragma,		pseudo_emit_starpragma,		lwasm_insn_normal},
+	{ "opt",		{	-1, 	-1, 	-1, 	-1},	pseudo_parse_starpragma,pseudo_resolve_starpragma,		pseudo_emit_starpragma,		lwasm_insn_normal},
 	{ "*pragmapush",	{	-1,	-1, 	-1,	-1},	pseudo_parse_starpragmapush, pseudo_resolve_starpragmapush, pseudo_emit_starpragmapush,	lwasm_insn_normal},
 	{ "*pragmapop",	{	-1,	-1, 	-1,	-1},	pseudo_parse_starpragmapop, pseudo_resolve_starpragmapop, pseudo_emit_starpragmapop,	lwasm_insn_normal},
 	
@@ -717,11 +773,39 @@
 	{ "nam",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 	{ "pag",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 	{ "page",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
-	{ "opt",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 	{ "spc",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 	{ "ttl",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 	{ ".bank",		{	-1, 	-1, 	-1, 	-1 },	pseudo_parse_noop,		pseudo_resolve_noop,			pseudo_emit_noop,			lwasm_insn_normal},
 
+	// for 6800 compatibility
+	{ "aba",		{	0x3404,	0xabe0,	-1,		12 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "cba",		{	0x3404,	0xa1e0,	-1,		12 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "clc",		{	0x1cfe,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "clf",		{	0x1cbf,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "cli",		{	0x1cef,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "clif",		{	0x1caf,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "clv",		{	0x1cfd,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "cpx",		{	0x9c,	0xac,	0xbc,	0x8c}, 	insn_parse_gen16,		insn_resolve_gen16,				insn_emit_gen16,			lwasm_insn_is6800},
+	{ "des",		{	0x327f,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "dex",		{	0x301f,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "dey",		{	0x313f,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "ins",		{	0x3261,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "inx",		{	0x3001,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "iny",		{	0x3121,	-1,		-1,		 5 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "sba",		{	0x3404,	0xa0e0,	-1,		12 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "sec",		{	0x1a01,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "sef",		{	0x1a40,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "sei",		{	0x1a10,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "seif",		{	0x1a50,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "sev",		{	0x1a02,	-1,		-1,		 3 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "tab",		{	0x1f89,	0x4d,	-1,		 8 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "tap",		{	0x1f8a,	-1,		-1,		 6 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "tba",		{	0x1f98,	0x4d,	-1,		 8 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "tpa",		{	0x1fa8,	-1,		-1,		 6 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "tsx",		{	0x1f41,	-1,		-1,		 6 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "txs",		{	0x1f14,	-1,		-1,		 6 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+	{ "wai",		{	0x3cff,	-1,		-1,		22 },	insn_parse_inh6800,		insn_resolve_inh6800,			insn_emit_inh6800,			lwasm_insn_is6800 },
+
 	// flag end of table
-	{ NULL,			{	-1, 	-1, 	-1, 	-1 },	NULL,					NULL,							lwasm_insn_normal}
+	{ NULL,			{	-1, 	-1, 	-1, 	-1 },	NULL,					NULL,							NULL,						lwasm_insn_normal}
 };
--- a/lwasm/instab.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/instab.h	Mon Aug 05 21:27:09 2019 -0600
@@ -38,13 +38,18 @@
 
 enum
 {
-	lwasm_insn_cond = 1,		/* conditional instruction */
-	lwasm_insn_endm = 2,		/* end of macro */
-	lwasm_insn_setsym = 4,		/* insn sets symbol address */
-	lwasm_insn_is6309 = 8,		/* insn is 6309 only */
-	lwasm_insn_struct = 16,		/* insn allowed in a struct */
-	lwasm_insn_setdata = 32,	/* insn uses the data address for symbols */
-	lwasm_insn_normal = 0
+	lwasm_insn_cond			= 1,		/* conditional instruction */
+	lwasm_insn_endm			= 1 << 1,	/* end of macro */
+	lwasm_insn_setsym		= 1 << 2,	/* insn sets symbol address */
+	lwasm_insn_is6309		= 1 << 3,	/* insn is 6309 only */
+	lwasm_insn_struct		= 1 << 4,	/* insn allowed in a struct */
+	lwasm_insn_setdata		= 1 << 5,	/* insn uses the data address for symbols */
+	lwasm_insn_is6800		= 1 << 6,	/* insn is a 6800 compatibility operation */
+	lwasm_insn_is6809		= 1 << 7,	/* insn is 6809 only */
+	lwasm_insn_is6809conv	= 1 << 8,	/* insn is 6809 convenience only */
+	lwasm_insn_is6309conv	= 1 << 9,	/* insn is 6309 convenience only */
+	lwasm_insn_isemuext		= 1 << 10,	/* insn is an emulator extension */
+	lwasm_insn_normal		= 0
 };
 
 
@@ -52,8 +57,6 @@
 #define RESOLVEFUNC(fn)	void (fn)(asmstate_t *as, line_t *l, int force)
 #define EMITFUNC(fn)	void (fn)(asmstate_t *as, line_t *l)
 
-#ifndef __instab_c_seen__
 extern instab_t instab[];
-#endif //__instab_c_seen__
 
 #endif //__instab_h_seen__
--- a/lwasm/list.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/list.c	Mon Aug 05 21:27:09 2019 -0600
@@ -44,27 +44,34 @@
 	char *tc;
 		
 	if (!(as -> flags & FLAG_LIST))
-		return;
-		
-	if (as -> list_file)
 	{
-		if (strcmp(as -> list_file, "-") == 0)
+		of = NULL;
+	}
+	else
+	{		
+		if (as -> list_file)
 		{
-			of = stdout;
+			if (strcmp(as -> list_file, "-") == 0)
+			{
+				of = stdout;
+			}
+			else
+				of = fopen(as -> list_file, "w");
 		}
 		else
-			of = fopen(as -> list_file, "w");
+			of = stdout;
+
+		if (!of)
+		{
+			fprintf(stderr, "Cannot open list file; list not generated\n");
+			return;
+		}
 	}
-	else
-		of = stdout;
-	if (!of)
-	{
-		fprintf(stderr, "Cannot open list file; list not generated\n");
-		return;
-	}
-	
+
 	for (cl = as -> line_head; cl; cl = nl)
 	{
+		char *linespec;
+
 		nl = cl -> next;
 		if (CURPRAGMA(cl, PRAGMA_NOLIST))
 		{
@@ -89,7 +96,8 @@
 					lwasm_error_t *e;
 					for (e = nl -> warn; e; e = e -> next)
 					{
-						printf("Warning: %s\n", e -> mess);
+						if (of != stdout) printf("Warning (%s:%d): %s\n", cl -> linespec, cl -> lineno,  e -> mess);
+						if (of) fprintf(of, "Warning: %s\n", e -> mess);
 					}
 				}
 				if (nc == 0)
@@ -117,7 +125,8 @@
 				lwasm_error_t *e;
 				for (e = cl -> warn; e; e = e -> next)
 				{
-					printf("Warning: %s\n", e -> mess);
+					if (of != stdout) printf("Warning (%s:%d): %s\n", cl -> linespec, cl -> lineno, e -> mess);
+					if (of) fprintf(of, "Warning: %s\n", e -> mess);
 				}
 			}
 			obytelen = cl -> outputl;
@@ -127,21 +136,23 @@
 				memmove(obytes, cl -> output, cl -> outputl);
 			}
 		}
-		if ((cl -> len < 1 && cl -> dlen < 1) && obytelen < 1)
+		if (cl -> hidecond && CURPRAGMA(cl, PRAGMA_NOEXPANDCOND))
+			continue;
+		if ((cl -> len < 1 && cl -> dlen < 1) && obytelen < 1 && (cl -> symset == 1 || cl -> sym == NULL) )
 		{
 			if (cl -> soff >= 0)
 			{
-				fprintf(of, "%04Xs                 ", cl -> soff & 0xffff);
+				if (of) fprintf(of, "%04Xs                 ", cl -> soff & 0xffff);
 			}
 			else if (cl -> dshow >= 0)
 			{
 				if (cl -> dsize == 1)
 				{
-					fprintf(of, "     %02X               ", cl -> dshow & 0xff);
+					if (of) fprintf(of, "     %02X               ", cl -> dshow & 0xff);
 				}
 				else
 				{
-					fprintf(of, "     %04X               ", cl -> dshow & 0xff);
+					if (of) fprintf(of, "     %04X               ", cl -> dshow & 0xff);
 				}
 			}
 			else if (cl -> dptr)
@@ -154,17 +165,17 @@
 				as -> exportcheck = 0;
 				if (lw_expr_istype(te, lw_expr_type_int))
 				{
-					fprintf(of, "     %04X             ", lw_expr_intval(te) & 0xffff);
+					if (of) fprintf(of, "     %04X             ", lw_expr_intval(te) & 0xffff);
 				}
 				else
 				{
-					fprintf(of, "     ????             ");
+					if (of) fprintf(of, "     ????             ");
 				}
 				lw_expr_destroy(te);
 			}
 			else
 			{
-				fprintf(of, "                      ");
+				if (of) fprintf(of, "                      ");
 			}
 		}
 		else
@@ -178,48 +189,118 @@
 			as -> csect = cl -> csect;
 			lwasm_reduce_expr(as, te);
 			as -> exportcheck = 0;
-//			fprintf(of, "%s\n", lw_expr_print(te));
-			fprintf(of, "%04X%c", lw_expr_intval(te) & 0xffff, ((cl -> inmod || (cl -> dlen != cl -> len)) && instab[cl -> insn].flags & lwasm_insn_setdata) ? '.' : ' ');
+//			if (of) fprintf(of, "%s\n", lw_expr_print(te));
+			if (of) fprintf(of, "%04X%c", lw_expr_intval(te) & 0xffff, ((cl -> inmod || (cl -> dlen != cl -> len)) && instab[cl -> insn].flags & lwasm_insn_setdata) ? '.' : ' ');
 			lw_expr_destroy(te);
 			for (i = 0; i < obytelen && i < 8; i++)
 			{
-				fprintf(of, "%02X", obytes[i]);
+				if (of) fprintf(of, "%02X", obytes[i]);
 			}
 			for (; i < 8; i++)
 			{
-				fprintf(of, "  ");
+				if (of) fprintf(of, "  ");
 			}
-			fprintf(of, " ");
+			if (of) fprintf(of, " ");
+		}
+
+		/* the format specifier below is deliberately chosen so that the start of the line text is at
+		a multiple of 8 from the start of the list line */
+
+		#define max_linespec_len 17
+
+		// trim "include:" if it appears
+		if (as -> listnofile)
+		{
+			if (of) fprintf(of, "%05d ", cl->lineno);
 		}
-		/* the 32.32 below is deliberately chosen so that the start of the line text is at
-		   a multiple of 8 from the start of the list line */
-		fprintf(of, "(%32.32s):%05d ", cl -> linespec, cl -> lineno);
-		i = 0;
-		for (tc = cl -> ltext; *tc; tc++)
+		else
+		{
+			linespec = cl -> linespec;
+			if ((strlen(linespec) > 8) && (linespec[7] == ':')) linespec += 8;
+			while (*linespec == ' ') linespec++;
+
+			if (of) fprintf(of, "(%*.*s):%05d ", max_linespec_len, max_linespec_len, linespec, cl->lineno);
+		}
+		
+		if (CURPRAGMA(cl, PRAGMA_CC))
 		{
-			if ((*tc) == '\t')
+			as->cycle_total = 0;
+		}
+
+		/* display cycle counts */
+		char s[64] = "";
+		if (CURPRAGMA(cl, PRAGMA_C) || CURPRAGMA(cl, PRAGMA_CD))
+		{
+			if (cl->cycle_base != 0)
 			{
-				if (i % 8 == 0)
+				char ch = '(';
+				if (CURPRAGMA(cl, PRAGMA_6809)) ch = '[';
+
+				if (CURPRAGMA(cl, PRAGMA_CD) && cl->cycle_flags & CYCLE_ADJ)
 				{
-					i += 8;
-					fprintf(of, "        ");
+					sprintf(s, "%c%d+%d", ch, cl->cycle_base, cl->cycle_adj);	/* detailed cycle count */
 				}
 				else
 				{
-					while (i % 8)
+					sprintf(s, "%c%d", ch, cl->cycle_base + cl->cycle_adj);   /* normal cycle count*/
+				}
+
+				if (cl->cycle_flags & CYCLE_ESTIMATED)
+					strcat(s, "+?");
+
+				as->cycle_total += cl->cycle_base + cl->cycle_adj;
+
+				ch = ')';
+				if (CURPRAGMA(cl, PRAGMA_6809)) ch = ']';
+				sprintf(s, "%s%c", s, ch);
+			}
+		}
+
+		if (of) fprintf(of, "%-8s", s);
+
+		if (CURPRAGMA(cl, PRAGMA_CT)) 
+		{
+			if (cl->cycle_base != 0)
+			{
+				if (of) fprintf(of, "%-8d", as->cycle_total);
+			}
+			else
+			{
+				if (of) fprintf(of, "        ");
+			}
+		}
+
+		if (as -> tabwidth == 0)
+		{
+			fputs(cl -> ltext, of);
+		}
+		else 
+		{
+			i = 0;
+			for (tc = cl -> ltext; *tc; tc++)
+			{
+				if ((*tc) == '\t')
+				{
+					if (i % as -> tabwidth == 0)
 					{
-						fputc(' ', of);
+						if (of) fputc(' ', of);
+						i++;
+					}
+					while (i % as -> tabwidth)
+					{
+						if (of) fputc(' ', of);
 						i++;
 					}
 				}
-			}
-			else
-			{
-				fputc(*tc, of);
-				i++;
+				else
+				{
+					if (of) fputc(*tc, of);
+					i++;
+				}
 			}
 		}
-		fputc('\n', of);
+		if (of) fputc('\n', of);
+
 		if (obytelen > 8)
 		{
 			for (i = 8; i < obytelen; i++)
@@ -227,18 +308,24 @@
 				if (i % 8 == 0)
 				{
 					if (i != 8)
-						fprintf(of, "\n     ");
+					{
+						if (of) fprintf(of, "\n     ");
+					}
 					else
-						fprintf(of, "     ");
+					{
+						if (of) fprintf(of, "     ");
+					}
 				}
-				fprintf(of, "%02X", obytes[i]);
+				if (of) fprintf(of, "%02X", obytes[i]);
 			}
 			if (i > 8)
-				fprintf(of, "\n");
+				if (of) fprintf(of, "\n");
 		}
 		lw_free(obytes);
 		obytes = NULL;
 	}
-	if ((as -> flags & FLAG_SYMBOLS))
+	if ((as -> flags & FLAG_SYMBOLS) && of)
 		list_symbols(as, of);
+	if (of && of != stdout)
+		fclose(of);
 }
--- a/lwasm/lwasm.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/lwasm.c	Mon Aug 05 21:27:09 2019 -0600
@@ -19,8 +19,6 @@
 this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define ___lwasm_c_seen___
-
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
@@ -29,10 +27,19 @@
 #include <lw_expr.h>
 #include <lw_alloc.h>
 #include <lw_string.h>
+#include <lw_error.h>
 
 #include "lwasm.h"
+#include "instab.h"
 
-void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...);
+void lwasm_skip_to_next_token(line_t *cl, char **p)
+{
+	if (CURPRAGMA(cl, PRAGMA_NEWSOURCE))
+	{
+		for (; **p && isspace(**p); (*p)++)
+			/* do nothing */ ;
+	}
+}
 
 int lwasm_expr_exportable(asmstate_t *as, lw_expr_t expr)
 {
@@ -47,7 +54,7 @@
 void lwasm_dividezero(void *priv)
 {
 	asmstate_t *as = (asmstate_t *)priv;
-	lwasm_register_error(as, as -> cl, "Division by zero");
+	lwasm_register_error(as, as -> cl, E_DIV0);
 }
 
 lw_expr_t lwasm_evaluate_var(char *var, void *priv)
@@ -57,15 +64,18 @@
 	importlist_t *im;
 	struct symtabe *s;
 	
+	debug_message(as, 225, "eval var: look up %s", var);
 	s = lookup_symbol(as, as -> cl, var);
 	if (s)
 	{
+		debug_message(as, 225, "eval var: symbol found %s = %s (%p)", s -> symbol, lw_expr_print(s -> value), s);
 		e = lw_expr_build(lw_expr_type_special, lwasm_expr_syment, s);
 		return e;
 	}
 	
 	if (as -> undefzero)
 	{
+		debug_message(as, 225, "eval var: undefined symbol treated as 0");
 		e = lw_expr_build(lw_expr_type_int, 0);
 		return e;
 	}
@@ -84,6 +94,7 @@
 	// check for "undefined" to import automatically
 	if ((as -> passno != 0) && !im && CURPRAGMA(as -> cl, PRAGMA_UNDEFEXTERN))
 	{
+		debug_message(as, 225, "eval var: importing undefined symbol");
 		im = lw_alloc(sizeof(importlist_t));
 		im -> symbol = lw_strdup(var);
 		im -> next = as -> importlist;
@@ -99,8 +110,9 @@
 nomatch:
 	if (as -> badsymerr)
 	{
-		lwasm_register_error(as, as -> cl, "Undefined symbol %s", var);
+		lwasm_register_error2(as, as -> cl, E_SYMBOL_UNDEFINED, "%s", var);
 	}
+	debug_message(as, 225, "eval var: undefined symbol - returning NULL");
 	return NULL;
 }
 
@@ -112,6 +124,10 @@
 		{
 //			sectiontab_t *s = priv;
 			asmstate_t *as = priv;
+			if (((sectiontab_t *)ptr) -> tbase != -1)
+			{
+				return lw_expr_build(lw_expr_type_int, ((sectiontab_t *)ptr) -> tbase);
+			}
 			if (as -> exportcheck && ptr == as -> csect)
 				return lw_expr_build(lw_expr_type_int, 0);
 			if (((sectiontab_t *)ptr) -> flags & section_flag_constant)
@@ -205,93 +221,208 @@
 	return NULL;
 }
 
-void lwasm_register_error_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
+const char* lwasm_lookup_error(lwasm_errorcode_t error_code)
 {
-	lwasm_error_t *e;
-	char errbuff[1024];
+	switch (error_code)
+	{
+		case E_6309_INVALID:			return "Illegal use of 6309 instruction in 6809 mode";
+		case E_6809_INVALID:			return "Illegal use of 6809 instruction in 6309 mode";
+		case E_ALIGNMENT_INVALID:		return "Invalid alignment";
+		case E_BITNUMBER_INVALID:		return "Invalid bit number";
+		case E_BITNUMBER_UNRESOLVED:	return "Bit number must be fully resolved";
+		case E_BYTE_OVERFLOW:			return "Byte overflow";
+		case E_CONDITION_P1:			return "Conditions must be constant on pass 1";
+		case E_DIRECTIVE_OS9_ONLY:		return "Directive only valid for OS9 target";
+		case E_DIV0:					return "Division by zero";
+		case E_EXEC_ADDRESS:			return "Exec address not constant!";
+		case E_EXPRESSION_BAD:			return "Bad expression";
+		case E_EXPRESSION_NOT_CONST:	return "Expression must be constant";
+		case E_EXPRESSION_NOT_RESOLVED: return "Expression not fully resolved";
+		case E_FILE_OPEN:				return "Cannot open file";
+		case E_FILENAME_MISSING:		return "Missing filename";
+		case E_FILL_INVALID:			return "Invalid fill length";
+		case E_IMMEDIATE_INVALID:		return "Immediate mode not allowed";
+		case E_IMMEDIATE_UNRESOLVED:	return "Immediate byte must be fully resolved";
+		case E_INSTRUCTION_FAILED:		return "Instruction failed to resolve.";
+		case E_INSTRUCTION_SECTION:		return "Instruction generating output outside of a section";
+		case E_LINE_ADDRESS:			return "Cannot resolve line address";
+		case E_LINED_ADDRESS:			return "Cannot resolve line data address";
+		case E_OBJTARGET_ONLY:			return "Only supported for object target";
+		case E_OPCODE_BAD:				return "Bad opcode";
+		case E_OPERAND_BAD:				return "Bad operand";
+		case E_PADDING_BAD:				return "Bad padding";
+		case E_PRAGMA_UNRECOGNIZED:		return "Unrecognized pragma string";
+		case E_REGISTER_BAD:			return "Bad register";
+		case E_SETDP_INVALID:			return "SETDP not permitted for object target";
+		case E_SETDP_NOT_CONST:			return "SETDP must be constant on pass 1";
+		case E_STRING_BAD:				return "Bad string condition";
+		case E_SYMBOL_BAD:				return "Bad symbol";
+		case E_SYMBOL_MISSING:			return "Missing symbol";
+		case E_SYMBOL_UNDEFINED:		return "Undefined symbol";
+		case E_SYMBOL_UNDEFINED_EXPORT: return "Undefined exported symbol";
+		case E_MACRO_DUPE:				return "Duplicate macro definition";
+		case E_MACRO_ENDM:				return "ENDM without MACRO";
+		case E_MACRO_NONAME:			return "Missing macro name";
+		case E_MACRO_RECURSE:			return "Attempt to define a macro inside a macro";
+		case E_MODULE_IN:				return "Already in a module!";
+		case E_MODULE_NOTIN:			return "Not in a module!";
+		case E_NEGATIVE_BLOCKSIZE:		return "Negative block sizes make no sense!";
+		case E_NEGATIVE_RESERVATION:	return "Negative reservation sizes make no sense!";
+		case E_NW_8:					return "n,W cannot be 8 bit";
+		case E_SECTION_END:				return "ENDSECTION without SECTION";
+		case E_SECTION_EXTDEP:			return "EXTDEP must be within a section";
+		case E_SECTION_FLAG:			return "Unrecognized section flag";
+		case E_SECTION_NAME:			return "Need section name";
+		case E_SECTION_TARGET:			return "Cannot use sections unless using the object target";
+		case E_STRUCT_DUPE:				return "Duplicate structure definition";
+		case E_STRUCT_NONAME:			return "Cannot declare a structure without a symbol name.";
+		case E_STRUCT_NOSYMBOL:			return "Structure definition with no effect - no symbol";
+		case E_STRUCT_RECURSE:			return "Attempt to define a structure inside a structure";
+		case E_SYMBOL_DUPE:				return "Multiply defined symbol";
+		case E_UNKNOWN_OPERATION:		return "Unknown operation";
+		case E_ORG_NOT_FOUND:			return "Previous ORG not found";
+		case E_COMPLEX_INCOMPLETE:      return "Incomplete expression too complex";
+		case E_USER_SPECIFIED:			return "User Specified:";
+		case E_ILL5:					return "Illegal 5 bit offset";
+
+		case W_ENDSTRUCT_WITHOUT:		return "ENDSTRUCT without STRUCT";
+		case W_DUPLICATE_SECTION:		return "Section flags can only be specified the first time; ignoring duplicate definition";
+		case W_NOT_SUPPORTED:			return "Not supported";
+		case W_OPERAND_SIZE:			return "Operand size larger than required";
+		default:						return "Error";
+	}
+}
+
+/* keeping this as a separate error output for stability in unit test scripts */
+void lwasm_error_testmode(line_t *cl, const char* msg, int fatal)
+{
+	cl -> as -> testmode_errorcount++;
+	fprintf(stderr, "line %d: %s : %s\n", cl->lineno, msg, cl->ltext);
+	if (fatal == 1) lw_error("aborting\n");
+}
+
+/* parse unit test input data from comment field */
+void lwasm_parse_testmode_comment(line_t *l, lwasm_testflags_t *flags, lwasm_errorcode_t *err, int *len, char **buf)
+{
+	*flags = 0;
 
 	if (!l)
 		return;
 
-	e = lw_alloc(sizeof(lwasm_error_t));
-	
-	e -> next = l -> err;
-	l -> err = e;
-	e -> charpos = -1;
-	
-	if (iptr)
-		e -> charpos = iptr - l -> ltext + 1;
-	
-	as -> errorcount++;
-	
-	(void)vsnprintf(errbuff, 1024, msg, args);
-	e -> mess = lw_strdup(errbuff);
+	char* s = strstr(l -> ltext, ";.");
+	if (s == NULL) return;
+
+	char* t = strstr(s, ":");
+	if (t == NULL)
+	{
+		/* parse: ;.8E0FCE (emitted code) */
+
+		if (buf == NULL) return;
+
+		int i;
+		*flags = TF_EMIT;
+
+		s = s + 2;	/* skip ;. prefix */
+		t = s;
+		while (*t > 32) t++;
+
+		if ((t - s) & 1)
+		{
+			lwasm_error_testmode(l, "bad test data (wrong length of hex chars)", 1);
+			return;
+		}
+
+		*len = (t - s) / 2;
+
+		t = lw_alloc(*len);
+		*buf = t;
+
+		for (i = 0; i < *len; i++)
+		{
+			int val;
+			sscanf(s, "%2x", &val);
+			*t++ = (char) val;
+			s += 2;
+		}
+	}
+	else
+	{
+		/* parse: ;.E:1000 or ;.E:7 (warnings or errors) */
+		*flags = TF_ERROR;
+
+		char ch = toupper(*(t - 1));
+		if (ch != 'E') lwasm_error_testmode(l, "bad test data (expected E: flag)", 1);
+		sscanf(t + 1, "%d", (int*) err);
+	}
 }
 
-void lwasm_register_error(asmstate_t *as, line_t *l, const char *msg, ...)
-{
-	va_list args;
-	
-	va_start(args, msg);
-	
-	lwasm_register_error_real(as, l, NULL, msg, args);
-	
-	va_end(args);
-}
-
-void lwasm_register_error_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
-{
-	va_list args;
-	
-	va_start(args, msg);
-	
-	lwasm_register_error_real(as, l, iptr, msg, args);
-	
-	va_end(args);
-}
-
-void lwasm_register_warning_real(asmstate_t *as, line_t *l, char *iptr, const char *msg, va_list args)
+void lwasm_register_error_real(asmstate_t *as, line_t *l, lwasm_errorcode_t error_code, const char *msg)
 {
 	lwasm_error_t *e;
-	char errbuff[1024];
-	
+
 	if (!l)
 		return;
 
+	if (CURPRAGMA(l, PRAGMA_TESTMODE))
+	{
+		lwasm_testflags_t flags;
+		lwasm_errorcode_t testmode_error_code;
+		lwasm_parse_testmode_comment(l, &flags, &testmode_error_code, NULL, NULL);
+		if (flags == TF_ERROR)
+		{
+			l -> len = 0;	/* null out bogus line */
+			l -> insn = -1;
+			l -> err_testmode = error_code;
+			if (testmode_error_code == error_code) return;		/* expected error: ignore and keep assembling */
+
+			char buf[128];
+			sprintf(buf, "wrong error code (%d)", error_code);
+			lwasm_error_testmode(l, buf, 0);
+			return;
+		}
+	}
+
 	e = lw_alloc(sizeof(lwasm_error_t));
+
+	if (error_code >= 1000)
+	{
+		e->next = l->warn;
+		l->warn = e;
+		as->warningcount++;
+	}
+	else
+	{
+		e->next = l->err;
+		l->err = e;
+		as->errorcount++;
+	}
 	
-	e -> next = l -> warn;
-	l -> warn = e;
-	
+	e -> code = error_code;
 	e -> charpos = -1;
-	if (iptr)
-		e -> charpos = iptr - l -> ltext + 1;
-	
-	as -> warningcount++;
-	
-	(void)vsnprintf(errbuff, 1024, msg, args);
-	e -> mess = lw_strdup(errbuff);
+
+	e -> mess = lw_strdup(msg);
 }
 
-void lwasm_register_warning(asmstate_t *as, line_t *l, const char *msg, ...)
+void lwasm_register_error(asmstate_t *as, line_t *l, lwasm_errorcode_t err)
 {
-	va_list args;
-	
-	va_start(args, msg);
-	
-	lwasm_register_warning_real(as, l, NULL, msg, args);
-	
-	va_end(args);
+	lwasm_register_error_real(as, l, err, lwasm_lookup_error(err));
 }
 
-void lwasm_register_warning_n(asmstate_t *as, line_t *l, char *iptr, const char *msg, ...)
+void lwasm_register_error2(asmstate_t *as, line_t *l, lwasm_errorcode_t err, const char* fmt, ...)
 {
+	char errbuff[1024];
+	char f[128];
+
+	sprintf(f, "%s %s", lwasm_lookup_error(err), fmt);
+
 	va_list args;
-	
-	va_start(args, msg);
-	
-	lwasm_register_warning_real(as, l, iptr, msg, args);
-	
+
+	va_start(args, fmt);
+
+	(void) vsnprintf(errbuff, 1024, f, args);
+
+	lwasm_register_error_real(as, l, err, errbuff);
+
 	va_end(args);
 }
 
@@ -305,9 +436,11 @@
 
 void lwasm_emit(line_t *cl, int byte)
 {
+	if (CURPRAGMA(cl, PRAGMA_NOOUTPUT))
+		return;
 	if (cl -> as -> output_format == OUTPUT_OBJ && cl -> csect == NULL)
 	{
-		lwasm_register_error(cl -> as, cl, "Instruction generating output outside of a section");
+		lwasm_register_error(cl -> as, cl, E_INSTRUCTION_SECTION);
 		return;
 	}
 	if (cl -> outputl < 0)
@@ -348,6 +481,9 @@
 
 void lwasm_emitop(line_t *cl, int opc)
 {
+	if (cl->cycle_base == 0)
+		lwasm_cycle_update_count(cl, opc);	/* only call first time, never on postbyte */
+
 	if (opc > 0x100)
 		lwasm_emit(cl, opc >> 8);
 	lwasm_emit(cl, opc);
@@ -402,9 +538,35 @@
 			return NULL;
 		v = (unsigned char)**p << 8 | (unsigned char)*((*p)+1);
 		(*p) += 2;
+		
+		if (**p == '"')
+			(*p)++;
+		
 		return lw_expr_build(lw_expr_type_int, v);
 	}
 	
+	/* double ASCII constant, like LDD #'MG */
+	if (CURPRAGMA(as->cl, PRAGMA_M80EXT))
+	{
+		if (((**p == '"') || (**p == '\'')) && (as->cl->genmode == 16))
+		{
+			int v;
+			(*p)++;
+			if (!**p)
+				return NULL;
+			if (!*((*p) + 1))
+				return NULL;
+			v = (unsigned char) **p << 8 | (unsigned char) *((*p) + 1);
+			(*p) += 2;
+
+			if ((**p == '"') || (**p == '\''))
+				(*p)++;
+
+			return lw_expr_build(lw_expr_type_int, v);
+		}
+	}
+
+	/* single ASCII constant, like LDA #'E */
 	if (**p == '\'')
 	{
 		int v;
@@ -415,6 +577,10 @@
 		
 		v = (unsigned char)**p;
 		(*p)++;
+		
+		if (**p == '\'')
+			(*p)++;
+		
 		return lw_expr_build(lw_expr_type_int, v);
 	}
 	
@@ -430,8 +596,13 @@
 			neg = -1;
 		}
 
-		if (!strchr("0123456789", **p))
+		if (!**p || !strchr("0123456789", **p))
+		{
+			(*p)--;
+			if (neg < 0)
+				(*p)--;
 			return NULL;
+		}
 
 		while (**p && strchr("0123456789", **p))
 		{
@@ -454,7 +625,12 @@
 		}
 
 		if (**p != '0' && **p != '1')
+		{
+			(*p)--;
+			if (neg < 0)
+				(*p)--;
 			return NULL;
+		}
 
 		while (**p && (**p == '0' || **p == '1'))
 		{
@@ -475,9 +651,13 @@
 			neg = -1;
 		}
 
-		if (!strchr("0123456789abcdefABCDEF", **p))
+		if (!**p || !strchr("0123456789abcdefABCDEF", **p))
+		{
+			(*p)--;
+			if (neg < 0)
+				(*p)--;
 			return NULL;
-
+		}
 		while (**p && strchr("0123456789abcdefABCDEF", **p))
 		{
 			v2 = toupper(**p) - '0';
@@ -495,9 +675,11 @@
 		int v = 0, v2;
 		(*p)+=2;
 
-		if (!strchr("0123456789abcdefABCDEF", **p))
+		if (!**p || !strchr("0123456789abcdefABCDEF", **p))
+		{
+			(*p) -= 2;
 			return NULL;
-
+		}
 		while (**p && strchr("0123456789abcdefABCDEF", **p))
 		{
 			v2 = toupper(**p) - '0';
@@ -521,9 +703,14 @@
 		}
 
 
-		if (!strchr("01234567", **p))
+		if (!**p || !strchr("01234567", **p))
+		{
+			(*p)--;
+			if (neg < 0)
+				(*p)--;
 			return NULL;
-
+		}
+		
 		while (**p && strchr("01234567", **p))
 		{
 			v = v * 8 + (**p - '0');
@@ -702,9 +889,24 @@
 lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p)
 {
 	lw_expr_t e;
-	
-	e = lw_expr_parse(p, as);
-	
+
+	if (as->exprwidth != 16)	
+	{
+		lw_expr_setwidth(as->exprwidth);
+		if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE))
+			e = lw_expr_parse(p, as);
+		else
+			e = lw_expr_parse_compact(p, as);
+		lw_expr_setwidth(0);
+	}
+	else
+	{
+		if (CURPRAGMA(as -> cl, PRAGMA_NEWSOURCE))
+			e = lw_expr_parse(p, as);
+		else
+			e = lw_expr_parse_compact(p, as);
+	}
+	lwasm_skip_to_next_token(as -> cl, p);
 	return e;
 }
 
@@ -750,12 +952,55 @@
 	return NULL;
 }
 
-void skip_operand(char **p)
+void skip_operand_real(line_t *cl, char **p)
 {
+	if (CURPRAGMA(cl, PRAGMA_NEWSOURCE))
+		return;
 	for (; **p && !isspace(**p); (*p)++)
 		/* do nothing */ ;
 }
 
+struct auxdata {
+	int v;
+	int oc;
+	int ms;
+};
+
+int lwasm_emitexpr_auxlwmod(lw_expr_t expr, void *arg)
+{
+	struct auxdata *ad = arg;
+	if (lw_expr_istype(expr, lw_expr_type_int))
+	{
+		ad -> v = lw_expr_intval(expr);
+		return 0;
+	}
+	if (lw_expr_istype(expr, lw_expr_type_special))
+	{
+		if (lw_expr_specint(expr) == lwasm_expr_secbase)
+		{
+			sectiontab_t *s;
+			s = lw_expr_specptr(expr);
+			if (strcmp(s -> name, "main") == 0)
+			{
+				ad -> ms = 1;
+				return 0;
+			}
+			if (strcmp(s -> name, "bss"))
+				return -1;
+			return 0;
+		}
+		return -1;
+	}
+	if (lw_expr_whichop(expr) == lw_expr_oper_plus)
+	{
+		if (ad -> oc)
+			return -1;
+		ad -> oc = 1;
+		return 0;
+	}
+	return -1;
+}
+
 int lwasm_emitexpr(line_t *l, lw_expr_t expr, int size)
 {
 	int v = 0;
@@ -772,14 +1017,85 @@
 	// handle external/cross-section/incomplete references here
 	else
 	{
-		if (l -> as -> output_format == OUTPUT_OBJ)
+		if (l -> as -> output_format == OUTPUT_LWMOD)
+		{
+			reloctab_t *re;
+			lw_expr_t te;
+			struct auxdata ad;
+			ad.v = 0;
+			ad.oc = 0;
+			ad.ms = 0;
+			
+			if (l -> csect == NULL)
+			{
+				lwasm_register_error(l -> as, l, E_INSTRUCTION_SECTION);
+				return -1;
+			}
+			if (size != 2)
+			{
+				lwasm_register_error(l -> as, l, E_OPERAND_BAD);
+				return -1;
+			}
+			// we have a 16 bit reference here - we need to check to make sure
+			// it's at most a + or - with the BSS section base
+			v = lw_expr_whichop(expr);
+			if (v == -1)
+			{
+				v = 0;
+				if (lw_expr_testterms(expr, lwasm_emitexpr_auxlwmod, &ad) != 0)
+				{
+					lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
+					return -1;
+				}
+				v = ad.v;
+			}
+			else if (v == lw_expr_oper_plus)
+			{
+				v = 0;
+				if (lw_expr_operandcount(expr) > 2)
+				{
+					lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
+					return -1;
+				}
+				if (lw_expr_testterms(expr, lwasm_emitexpr_auxlwmod, &ad) != 0)
+				{
+					lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
+					return -1;
+				}
+				v = ad.v;
+			}
+			else
+			{
+				lwasm_register_error(l -> as, l, E_COMPLEX_INCOMPLETE);
+				return -1;
+			}
+
+			// add "expression" record to section table
+			re = lw_alloc(sizeof(reloctab_t));
+			re -> next = l -> csect -> reloctab;
+			l -> csect -> reloctab = re;
+			te = lw_expr_build(lw_expr_type_int, ol);
+			re -> offset = lw_expr_build(lw_expr_type_oper, lw_expr_oper_plus, l -> addr, te);
+			lw_expr_destroy(te);
+			lwasm_reduce_expr(l -> as, re -> offset);
+			re -> size = size;
+			if (ad.ms == 1)
+				re -> expr = lw_expr_copy(expr);
+			else
+				re -> expr = NULL;
+
+			lwasm_emit(l, v >> 8);
+			lwasm_emit(l, v & 0xff);
+			return 0;
+		}
+		else if (l -> as -> output_format == OUTPUT_OBJ)
 		{
 			reloctab_t *re;
 			lw_expr_t te;
 
 			if (l -> csect == NULL)
 			{
-				lwasm_register_error(l -> as, l, "Instruction generating output outside of a section");
+				lwasm_register_error(l -> as, l, E_INSTRUCTION_SECTION);
 				return -1;
 			}
 			
@@ -833,7 +1149,7 @@
 				lwasm_emit(l, 0);
 			return 0;
 		}
-		lwasm_register_error(l -> as, l, "Expression not fully resolved");
+		lwasm_register_error(l->as, l, E_EXPRESSION_NOT_RESOLVED);
 		return -1;
 	}
 	
@@ -921,13 +1237,19 @@
 	{
 		if (!(cl -> err) && !(cl -> warn))
 			continue;
+
+		// trim "include:" if it appears
+		char* s = cl->linespec;
+		if ((strlen(s) > 8) && (s[7] == ':')) s += 8;
+		while (*s == ' ') s++;
+
 		for (e = cl -> err; e; e = e -> next)
 		{
-			fprintf(stderr, "ERROR: %s\n", e -> mess);
+			fprintf(stderr, "%s(%d) : ERROR : %s\n", s, cl->lineno, e->mess);
 		}
 		for (e = cl -> warn; e; e = e -> next)
 		{
-			fprintf(stderr, "WARNING: %s\n", e -> mess);
+			fprintf(stderr, "%s(%d) : WARNING : %s\n", s, cl->lineno, e->mess);
 		}
 		fprintf(stderr, "%s:%05d %s\n\n", cl -> linespec, cl -> lineno, cl -> ltext);
 	}
@@ -937,8 +1259,8 @@
 this does any passes and other gymnastics that might be useful
 to see if an expression reduces early
 */
-extern void do_pass3(asmstate_t *as);
-extern void do_pass4_aux(asmstate_t *as, int force);
+void do_pass3(asmstate_t *as);
+void do_pass4_aux(asmstate_t *as, int force);
 
 void lwasm_interim_reduce(asmstate_t *as)
 {
@@ -956,7 +1278,7 @@
 	
 	if (!e)
 	{
-		lwasm_register_error(as, as -> cl, "Bad expression");
+		lwasm_register_error(as, as -> cl, E_EXPRESSION_BAD);
 		return NULL;
 	}
 
@@ -988,7 +1310,7 @@
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
 		debug_message(as, 250, "Non-constant expression");
-		lwasm_register_error(as, as -> cl, "Conditions must be constant on pass 1");
+		lwasm_register_error(as, as -> cl, E_CONDITION_P1);
 		return NULL;
 	}
 	debug_message(as, 250, "Returning expression");
@@ -1087,3 +1409,48 @@
 		return -1;
 	return 0;
 }
+
+void lwasm_reduce_line_exprs(line_t *cl)
+{
+	asmstate_t *as;
+	struct line_expr_s *le;
+	int i;
+			
+	as = cl -> as;
+	as -> cl = cl;
+			
+	// simplify address
+	lwasm_reduce_expr(as, cl -> addr);
+		
+	// simplify data address
+	lwasm_reduce_expr(as, cl -> daddr);
+
+	// simplify each expression
+	for (i = 0, le = cl -> exprs; le; le = le -> next, i++)
+	{
+		debug_message(as, 101, "Reduce expressions: (pre) exp[%d] = %s", i, lw_expr_print(le -> expr));
+		lwasm_reduce_expr(as, le -> expr);
+		debug_message(as, 100, "Reduce expressions: exp[%d] = %s", i, lw_expr_print(le -> expr));
+	}
+			
+	if (cl -> len == -1 || cl -> dlen == -1)
+	{
+		// try resolving the instruction length
+		// but don't force resolution
+		if (cl -> insn >= 0 && instab[cl -> insn].resolve)
+		{
+			(instab[cl -> insn].resolve)(as, cl, 0);
+			if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
+			{
+				if (cl -> len == 0)
+					cl -> len = cl -> dlen;
+				else
+					cl -> dlen = cl -> len;
+			}
+		}
+	}
+	debug_message(as, 100, "Reduce expressions: len = %d", cl -> len);
+	debug_message(as, 100, "Reduce expressions: dlen = %d", cl -> dlen);
+	debug_message(as, 100, "Reduce expressions: addr = %s", lw_expr_print(cl -> addr));
+	debug_message(as, 100, "Reduce expressions: daddr = %s", lw_expr_print(cl -> daddr));
+}
--- a/lwasm/lwasm.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/lwasm.h	Mon Aug 05 21:27:09 2019 -0600
@@ -22,10 +22,15 @@
 #ifndef ___lwasm_h_seen___
 #define ___lwasm_h_seen___
 
+#ifdef _MSC_VER
+#include <lw_win.h>	// windows build
+#endif
+
 #include <lw_expr.h>
 #include <lw_stringlist.h>
 #include <lw_stack.h>
 
+#include <version.h>
 
 // these are allowed chars BELOW 0x80 for symbols
 // first is symbol start chars, second is anywhere in symbol
@@ -50,16 +55,15 @@
 enum lwasm_output_e
 {
 	OUTPUT_DECB = 0,	// DECB multirecord format
+	OUTPUT_BASIC,		// Color BASIC program
 	OUTPUT_RAW,			// raw sequence of bytes
 	OUTPUT_OBJ,			// proprietary object file format
 	OUTPUT_RAWREL,		// raw bytes where ORG causes a SEEK in the file
-	OUTPUT_OS9			// os9 module target
-};
-
-enum lwasm_target_e
-{
-	TARGET_6309 = 0,	// target 6309 CPU
-	TARGET_6809			// target 6809 CPU (no 6309 ops)
+	OUTPUT_OS9,			// os9 module target
+	OUTPUT_SREC,		// motorola SREC format
+	OUTPUT_IHEX,		// intel hex format
+	OUTPUT_HEX,			// generic hexadecimal format
+	OUTPUT_LWMOD        // special module format for LW
 };
 
 enum lwasm_flags_e
@@ -69,27 +73,48 @@
 	FLAG_SYMBOLS = 0x004,
 	FLAG_DEPENDNOERR = 0x0008,
 	FLAG_UNICORNS = 0x0010,
+	FLAG_MAP = 0x0020,
+	FLAG_SYMBOLS_NOLOCALS = 0x0040,
+	FLAG_NOOUT = 0x80,
+	FLAG_SYMDUMP = 0x100,
 	FLAG_NONE = 0
 };
 
 enum lwasm_pragmas_e
 {
-	PRAGMA_NONE = 0,					// no pragmas in effect
-	PRAGMA_DOLLARNOTLOCAL = 0x0001,		// dollar sign does not make a symbol local
-	PRAGMA_NOINDEX0TONONE = 0x0002,		// do not change implicit 0,R to ,R
-	PRAGMA_UNDEFEXTERN = 0x0004,		// undefined symbols are considered to be external
-	PRAGMA_CESCAPES = 0x0008,			// allow C style escapes in fcc, fcs, fcn, etc.
-	PRAGMA_IMPORTUNDEFEXPORT = 0x0010,	// imports symbol if undefined upon export
-	PRAGMA_PCASPCR = 0x0020,			// treats ,PC as ,PCR instead of constant offset
-	PRAGMA_SHADOW = 0x0040,				// allow macros to shadow builtin operations
-	PRAGMA_NOLIST = 0x0080,				// don't show line in listing
-	PRAGMA_AUTOBRANCHLENGTH = 0x0100,	// automatically select proper length for relative branches
-	PRAGMA_EXPORT = 0x0200,				// export symbols by default, unless local
-	PRAGMA_SYMBOLNOCASE = 0x400,		// symbols defined under this pragma are matched case insensitively
-	PRAGMA_CONDUNDEFZERO = 0x800		// treat undefined symbols as zero in conditionals during pass 1
+	PRAGMA_NONE = 0,						// no pragmas in effect
+	PRAGMA_DOLLARNOTLOCAL 		= 1 << 0,	// dollar sign does not make a symbol local
+	PRAGMA_NOINDEX0TONONE 		= 1 << 1,	// do not change implicit 0,R to ,R
+	PRAGMA_UNDEFEXTERN			= 1 << 2,	// undefined symbols are considered to be external
+	PRAGMA_CESCAPES 			= 1 << 3,	// allow C style escapes in fcc, fcs, fcn, etc.
+	PRAGMA_IMPORTUNDEFEXPORT	= 1 << 4,	// imports symbol if undefined upon export
+	PRAGMA_PCASPCR				= 1 << 5,	// treats ,PC as ,PCR instead of constant offset
+	PRAGMA_SHADOW				= 1 << 6,	// allow macros to shadow builtin operations
+	PRAGMA_NOLIST				= 1 << 7,	// don't show line in listing
+	PRAGMA_AUTOBRANCHLENGTH		= 1 << 8,	// automatically select proper length for relative branches
+	PRAGMA_EXPORT				= 1 << 9,	// export symbols by default, unless local
+	PRAGMA_SYMBOLNOCASE			= 1 << 10,	// symbols defined under this pragma are matched case insensitively
+	PRAGMA_CONDUNDEFZERO		= 1 << 11,	// treat undefined symbols as zero in conditionals during pass 1
+	PRAGMA_6800COMPAT			= 1 << 12,	// enable 6800 compatibility opcodes
+	PRAGMA_FORWARDREFMAX		= 1 << 13,	// force incomplete references on pass 1 to maximum mode
+	PRAGMA_6809					= 1 << 14,	// 6809/6309 assembly mode
+	PRAGMA_TESTMODE				= 1 << 15,	// enable test mode (for internal unit testing)
+	PRAGMA_C					= 1 << 16,	// enable cycle counts
+	PRAGMA_CD					= 1 << 17,	// enable detailed cycle count
+	PRAGMA_CT					= 1 << 18,	// enable cycle count running total
+	PRAGMA_CC					= 1 << 19,	// clear cycle count running total
+	PRAGMA_QRTS					= 1 << 20,	// enable BRA ?RTS support
+	PRAGMA_M80EXT				= 1 << 21,	// enable Macro-80C assembler extensions
+	PRAGMA_6809CONV				= 1 << 22,	// enable 6809 convenience ops
+	PRAGMA_6309CONV				= 1 << 23,	// enable 6309 convenience ops
+	PRAGMA_NEWSOURCE			= 1 << 24,	// don't use compatibility source format
+	PRAGMA_OPERANDSIZE			= 1 << 25,	// warn if operand size is bigger than required
+	PRAGMA_EMUEXT				= 1 << 26,  // enable emulator extensions
+	PRAGMA_NOOUTPUT             = 1 << 27,  // disable object code output
+	PRAGMA_NOEXPANDCOND         = 1 << 28,  // hide conditionals and skipped output in listings
+	PRAGMA_CLEARBIT				= 1 << 31	// reserved to indicate negated pragma flag status
 };
 
-
 enum
 {
 	section_flag_bss = 1,				// BSS section
@@ -114,14 +139,93 @@
 	lw_expr_t offset;					// offset for next instance
 	int oblen;							// size of section output
 	int obsize;							// size of output buffer
+	int tbase;                          // temporary base value for resolution
 	unsigned char *obytes;				// output buffer
 	reloctab_t *reloctab;				// table of relocations
 	sectiontab_t *next;
 };
 
+typedef enum
+{
+	TF_EMIT = 1,
+	TF_ERROR = 2
+} lwasm_testflags_t;
+
+typedef enum 
+{
+	E_6309_INVALID				= 1,
+	E_6809_INVALID				= 2,
+	E_ALIGNMENT_INVALID			= 3,
+	E_BITNUMBER_UNRESOLVED		= 4,
+	E_BITNUMBER_INVALID			= 5,
+	E_BYTE_OVERFLOW				= 6,
+	E_CONDITION_P1				= 7,
+	E_DIRECTIVE_OS9_ONLY		= 8,
+	E_DIV0						= 9,
+	E_EXEC_ADDRESS				= 10,
+	E_FILL_INVALID				= 11,
+	E_IMMEDIATE_INVALID			= 12,
+	E_IMMEDIATE_UNRESOLVED		= 13,
+	E_EXPRESSION_BAD			= 14,
+	E_EXPRESSION_NOT_CONST		= 15,
+	E_EXPRESSION_NOT_RESOLVED	= 16,
+	E_FILE_OPEN					= 17,
+	E_FILENAME_MISSING			= 18,
+	E_INSTRUCTION_FAILED		= 19,
+	E_INSTRUCTION_SECTION		= 20,
+	E_LINE_ADDRESS				= 21,
+	E_LINED_ADDRESS				= 22,
+	E_MACRO_DUPE				= 23,
+	E_MACRO_ENDM				= 24,
+	E_MACRO_NONAME				= 25,
+	E_MACRO_RECURSE				= 26,
+	E_MODULE_IN					= 27,
+	E_MODULE_NOTIN				= 28,
+	E_NEGATIVE_BLOCKSIZE		= 29,
+	E_NEGATIVE_RESERVATION		= 30,
+	E_NW_8						= 31,
+	E_OPCODE_BAD				= 32,
+	E_OPERAND_BAD				= 33,
+	E_OBJTARGET_ONLY			= 34,
+	E_PADDING_BAD				= 35,
+	E_PRAGMA_UNRECOGNIZED		= 36,
+	E_REGISTER_BAD				= 37,
+	E_SECTION_END				= 38,
+	E_SECTION_EXTDEP			= 39,
+	E_SECTION_FLAG				= 40,
+	E_SECTION_NAME				= 41,
+	E_SECTION_TARGET			= 42,
+	E_SETDP_INVALID				= 43,
+	E_SETDP_NOT_CONST			= 44,
+	E_STRING_BAD				= 45,
+	E_STRUCT_DUPE				= 46,
+	E_STRUCT_NONAME				= 47,
+	E_STRUCT_NOSYMBOL			= 48,
+	E_STRUCT_RECURSE			= 49,
+	E_SYMBOL_BAD				= 50,
+	E_SYMBOL_DUPE				= 51,
+	E_SYMBOL_MISSING			= 52,
+	E_SYMBOL_UNDEFINED			= 53,
+	E_SYMBOL_UNDEFINED_EXPORT	= 54,
+	E_UNKNOWN_OPERATION			= 55,
+	E_USER_SPECIFIED			= 56,
+	E_ORG_NOT_FOUND				= 57,
+	E_COMPLEX_INCOMPLETE        = 58,
+	E_ILL5						= 59,
+	
+	/* warnings must be 1000 or greater */
+
+	W_DUPLICATE_SECTION			= 1000,
+	W_ENDSTRUCT_WITHOUT			= 1001,
+	W_NOT_SUPPORTED				= 1002,
+	W_USER_SPECIFIED			= 1003,
+	W_OPERAND_SIZE				= 1004
+} lwasm_errorcode_t;
+
 typedef struct lwasm_error_s lwasm_error_t;
 struct lwasm_error_s
 {
+	lwasm_errorcode_t code;				// error code
 	char *mess;							// actual error message
 	int charpos;						// character position on line where parsing stopped
 	lwasm_error_t *next;				// ptr to next error
@@ -152,6 +256,12 @@
 	importlist_t *next;					// next in the import list
 };
 
+typedef enum
+{
+	CYCLE_ADJ = 1,
+	CYCLE_ESTIMATED = 2
+} cycle_flags;
+
 struct line_s
 {
 	lw_expr_t addr;						// assembly address of the line
@@ -167,8 +277,14 @@
 	int outputl;						// size of output
 	int outputbl;						// size of output buffer
 	int dpval;							// direct page value
+	int cycle_base;						// base instruction cycle count
+	int cycle_adj;						// cycle adjustment
+	int	cycle_flags;					// cycle flags
+	int genmode;						// generation mode (insn_parse_gen0/8/16)
+	int fcc_extras;						// fcc extra bytes
 	lwasm_error_t *err;					// list of errors
 	lwasm_error_t *warn;				// list of errors
+	lwasm_errorcode_t err_testmode;		// error code in testmode
 	line_t *prev;						// previous line
 	line_t *next;						// next line
 	int inmod;							// inside a module?
@@ -178,6 +294,7 @@
 	int pb;								// pass forward post byte
 	int lint;							// pass forward integer
 	int lint2;							// another pass forward integer
+	int conditional_return;				// for ?RTS handling (1 if RTS follows)
 	asmstate_t *as;						// assembler state data ptr
 	int pragmas;						// pragmas in effect for the line
 	int context;						// the symbol context number
@@ -193,6 +310,7 @@
 	int noexpand_start;					// start of a no-expand block
 	int noexpand_end;					// end of a no-expand block
 	int hideline;						// set if we're going to hide this line on output	
+	int hidecond;                       // set if we're going to hide this line due to condition hiding
 };
 
 enum
@@ -261,13 +379,13 @@
 struct asmstate_s
 {
 	int output_format;					// output format
-	int target;							// assembly target
 	int debug_level;					// level of debugging requested
 	FILE *debug_file;					// FILE * to output debug messages to
 	int flags;							// assembly flags
 	int pragmas;						// pragmas currently in effect
 	int errorcount;						// number of errors encountered
 	int warningcount;					// number of warnings issued
+	int testmode_errorcount;			// number of errors in testmode
 	int inmacro;						// are we in a macro?
 	int instruct;						// are w in a structure?
 	int skipcond;						// skipping a condition?
@@ -275,10 +393,12 @@
 	int skipmacro;						// are we skipping in a macro?	
 	int endseen;						// have we seen an "end" pseudo?
 	int execaddr;						// address from "end"
+	lw_expr_t execaddr_expr;            // address from "end" but as an expression
 	int inmod;							// inside an os9 module?
 	int undefzero;						// used for handling "condundefzero"
 	int pretendmax;						// set if we need to pretend the instruction is max length
 	unsigned char crc[3];				// crc accumulator
+	int cycle_total;					// cycle count accumulator
 	int badsymerr;						// throw error on undef sym if set
 
 	line_t *line_head;					// start of lines list
@@ -297,6 +417,9 @@
 	exportlist_t *exportlist;			// list of exported symbols
 	importlist_t *importlist;			// list of imported symbols
 	char *list_file;					// name of file to list to
+	char *symbol_dump_file;				// name of file to dump symbol table to
+	int tabwidth;						// tab width in list file
+	char *map_file;						// name of map file
 	char *output_file;					// output file name	
 	lw_stringlist_t input_files;		// files to assemble
 	void *input_data;					// opaque data used by the input system
@@ -311,52 +434,66 @@
 	int passno;							// set to the current pass number
 	int preprocess;						// set if we are prepocessing
 	int fileerr;						// flags error opening file
+	int exprwidth;						// the bit width of the expression being evaluated
+	int listnofile;						// nonzero to suppress printing file name in listings
 };
 
-#ifndef ___symbol_c_seen___
+struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags);
+struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym);
+
+int parse_pragma_helper(char *p);
 
-extern struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags);
-extern struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym);
+int lwasm_cycle_calc_ind(line_t *cl);
+int lwasm_cycle_calc_rlist(line_t *cl);
+void lwasm_cycle_update_count(line_t *cl, int opc);
 
-#endif
-
-#ifndef ___lwasm_c_seen___
+void lwasm_parse_testmode_comment(line_t *cl, lwasm_testflags_t *flags, lwasm_errorcode_t *err, int *len, char **buf);
+void lwasm_error_testmode(line_t *cl, const char* msg, int fatal);
 
-extern void lwasm_register_error(asmstate_t *as, line_t *cl, const char *msg, ...);
-extern void lwasm_register_warning(asmstate_t *as, line_t *cl, const char *msg, ...);
+void lwasm_register_error(asmstate_t *as, line_t *cl, lwasm_errorcode_t err);
+void lwasm_register_error2(asmstate_t *as, line_t *cl, lwasm_errorcode_t err, const char* fmt, ...);
 
-extern void lwasm_register_error_n(asmstate_t *as, line_t *cl, char *iptr, const char *msg, ...);
-extern void lwasm_register_warning_n(asmstate_t *as, line_t *cl, char *iptr, const char *msg, ...);
+int lwasm_next_context(asmstate_t *as);
+void lwasm_emit(line_t *cl, int byte);
+void lwasm_emitop(line_t *cl, int opc);
 
-extern int lwasm_next_context(asmstate_t *as);
-extern void lwasm_emit(line_t *cl, int byte);
-extern void lwasm_emitop(line_t *cl, int opc);
+void lwasm_save_expr(line_t *cl, int id, lw_expr_t expr);
+lw_expr_t lwasm_fetch_expr(line_t *cl, int id);
+lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p);
+int lwasm_emitexpr(line_t *cl, lw_expr_t expr, int s);
 
-extern void lwasm_save_expr(line_t *cl, int id, lw_expr_t expr);
-extern lw_expr_t lwasm_fetch_expr(line_t *cl, int id);
-extern lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p);
-extern int lwasm_emitexpr(line_t *cl, lw_expr_t expr, int s);
+void skip_operand_real(line_t *l, char **p);
+/* this macro can only be used where "l" is the current line pointer */
+#define skip_operand(p) skip_operand_real(l, p)
 
-extern void skip_operand(char **p);
+int lwasm_lookupreg2(const char *rlist, char **p);
+int lwasm_lookupreg3(const char *rlist, char **p);
 
-extern int lwasm_lookupreg2(const char *rlist, char **p);
-extern int lwasm_lookupreg3(const char *rlist, char **p);
+void lwasm_show_errors(asmstate_t *as);
 
-extern void lwasm_show_errors(asmstate_t *as);
+int lwasm_reduce_expr(asmstate_t *as, lw_expr_t expr);
+
+lw_expr_t lwasm_parse_cond(asmstate_t *as, char **p);
 
-extern int lwasm_reduce_expr(asmstate_t *as, lw_expr_t expr);
+int lwasm_calculate_range(asmstate_t *as, lw_expr_t expr, int *min, int *max);
 
-extern lw_expr_t lwasm_parse_cond(asmstate_t *as, char **p);
-
-extern int lwasm_calculate_range(asmstate_t *as, lw_expr_t expr, int *min, int *max);
+void lwasm_reduce_line_exprs(line_t *cl);
 
-#endif
+#ifdef LWASM_NODEBUG
+#define debug_message(...)
+#define dump_state(...)
+#else
+void real_debug_message(asmstate_t *as, int level, const char *fmt, ...);
+void dump_state(asmstate_t *as);
 
-extern void debug_message(asmstate_t *as, int level, const char *fmt, ...);
-extern void dump_state(asmstate_t *as);
-
+#define debug_message(as,level,...) do { asmstate_t *ras = (as); int rlevel = (level); if (ras->debug_level >= rlevel) { real_debug_message(ras, rlevel, __VA_ARGS__); } } while (0)
+#endif
 
 #define OPLEN(op) (((op)>0xFF)?2:1)
 #define CURPRAGMA(l,p)	(((l) && ((l)->pragmas & (p))) ? 1 : 0)
 
+/* some functions for parsing */
+/* skip to the start of the next token if the current parsing mode allows it */
+void lwasm_skip_to_next_token(line_t *cl, char **p);
+
 #endif /* ___lwasm_h_seen___ */
--- a/lwasm/macro.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/macro.c	Mon Aug 05 21:27:09 2019 -0600
@@ -43,29 +43,30 @@
 	if (as -> skipcond)
 	{
 		as -> skipmacro = 1;
+		skip_operand(p);
 		return;
 	}
 	
 	if (as -> inmacro)
 	{
-		lwasm_register_error(as, l, "Attempt to define a macro inside a macro");
+		lwasm_register_error(as, l, E_MACRO_RECURSE);
 		return;
 	}
 	
 	if (!(l -> sym))
 	{
-		lwasm_register_error(as, l, "Missing macro name");
+		lwasm_register_error(as, l, E_MACRO_NONAME);
 		return;
 	}
 
 	for (m = as -> macros; m; m = m -> next)
 	{
-		if (!strcmp(m -> name, l -> sym))
+		if (!strcasecmp(m -> name, l -> sym))
 			break;
 	}
 	if (m)
 	{
-		lwasm_register_error(as, l, "Duplicate macro definition");
+		lwasm_register_error(as, l, E_MACRO_DUPE);
 		return;
 	}
 	
@@ -102,7 +103,7 @@
 	
 	if (!as -> inmacro)
 	{
-		lwasm_register_error(as, l, "ENDM without MACRO");
+		lwasm_register_error(as, l, E_MACRO_ENDM);
 		return;
 	}
 	
@@ -159,7 +160,7 @@
 
 	for (m = as -> macros; m; m = m -> next)
 	{
-		if (!strcmp(opc, m -> name))
+		if (!strcasecmp(opc, m -> name))
 			break;
 	}
 	// signal no macro expansion
--- a/lwasm/main.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/main.c	Mon Aug 05 21:27:09 2019 -0600
@@ -32,9 +32,9 @@
 #include "lwasm.h"
 #include "input.h"
 
-extern void lwasm_do_unicorns(asmstate_t *as);
+void lwasm_do_unicorns(asmstate_t *as);
 
-extern int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr);
+int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr);
 
 /* command line option handling */
 #define PROGVER "lwasm from " PACKAGE_STRING
@@ -44,9 +44,14 @@
 {
 	{ "output",		'o',	"FILE",		0,							"Output to FILE"},
 	{ "debug",		'd',	"LEVEL",	lw_cmdline_opt_optional,	"Set debug mode"},
-	{ "format",		'f',	"TYPE",		0,							"Select output format: decb, raw, obj, os9"},
+	{ "format",		'f',	"TYPE",		0,							"Select output format: decb, basic, raw, obj, os9, ihex, srec"},
 	{ "list",		'l',	"FILE",		lw_cmdline_opt_optional,	"Generate list [to FILE]"},
+	{ "list-nofiles", 0x104, 0,			0,							"Omit file names in list output"},
 	{ "symbols",	's',	0,			lw_cmdline_opt_optional,	"Generate symbol list in listing, no effect without --list"},
+	{ "symbols-nolocals", 0x103,	0,	lw_cmdline_opt_optional,	"Same as --symbols but with local labels ignored"},
+	{ "symbol-dump", 0x106, "FILE",		lw_cmdline_opt_optional,	"Dump global symbol table in assembly format" },
+	{ "tabs",		't',	"WIDTH",	0,							"Set tab spacing in listing (0=don't expand tabs)" },
+	{ "map",		'm',	"FILE",		lw_cmdline_opt_optional,	"Generate map [to FILE]"},
 	{ "decb",		'b',	0,			0,							"Generate DECB .bin format output, equivalent of --format=decb"},
 	{ "raw",		'r',	0,			0,							"Generate raw binary format output, equivalent of --format=raw"},
 	{ "obj",		0x100,	0,			0,							"Generate proprietary object file format for later linking, equivalent of --format=obj" },
@@ -56,9 +61,11 @@
 	{ "6809",		'9',	0,			0,							"Set assembler to 6809 only mode" },
 	{ "6309",		'3',	0,			0,							"Set assembler to 6309 mode (default)" },
 	{ "includedir",	'I',	"PATH",		0,							"Add entry to include path" },
-	{ "define", 'D', "SYM[=VAL]", 0, "Automatically define SYM to be VAL (or 1)"},
+	{ "define",		'D',	"SYM[=VAL]",0,							"Automatically define SYM to be VAL (or 1)"},
 	{ "preprocess",	'P',	0,			0,							"Preprocess macros and conditionals and output revised source to stdout" },
 	{ "unicorns",	0x142,	0,			0,							"Add sooper sekrit sauce"},
+	{ "6800compat",	0x200,	0,			0,							"Enable 6800 compatibility instructions, equivalent to --pragma=6800compat" },
+	{ "no-output",  0x105,  0,          0,                          "Inhibit creation of output file" },
 	{ 0 }
 };
 
@@ -98,13 +105,37 @@
 		if (as -> output_file)
 			lw_free(as -> output_file);
 		as -> output_file = lw_strdup(arg);
+		as -> flags &= ~FLAG_NOOUT;
+		break;
+
+	case 0x105:
+		as -> flags |= FLAG_NOOUT;
+		break;
+
+	case 0x106:
+		if (as -> symbol_dump_file)
+			lw_free(as -> symbol_dump_file);
+		if (!arg)
+			as -> symbol_dump_file = lw_strdup("-");
+		else
+			as -> symbol_dump_file = lw_strdup(arg);
+		as -> flags |= FLAG_SYMDUMP;
 		break;
 
 	case 'd':
+#ifdef LWASM_NODEBUG
+		fprintf(stderr, "This binary has been built without debugging message support\n");
+#else
 		if (!arg)
 			as -> debug_level = 50;
 		else
 			as -> debug_level = atoi(arg);
+#endif
+		break;
+
+	case 't':
+		if (arg)
+			as -> tabwidth = atoi(arg);
 		break;
 
 	case 'l':
@@ -117,10 +148,28 @@
 		as -> flags |= FLAG_LIST;
 		break;
 
+	case 'm':
+		if (as -> map_file)
+			lw_free(as -> map_file);
+		if (!arg)
+			as -> map_file = lw_strdup("-");
+		else
+			as -> map_file = lw_strdup(arg);
+		as -> flags |= FLAG_MAP;
+		break;
+
 	case 's':
 		as -> flags |= FLAG_SYMBOLS;
 		break;
-		
+
+	case 0x103:
+		as -> flags |= FLAG_SYMBOLS | FLAG_SYMBOLS_NOLOCALS;
+		break;
+
+	case 0x104:
+		as -> listnofile = 1;
+		break;
+
 	case 'b':
 		as -> output_format = OUTPUT_DECB;
 		break;
@@ -148,17 +197,29 @@
 	case 'f':
 		if (!strcasecmp(arg, "decb"))
 			as -> output_format = OUTPUT_DECB;
+		else if (!strcasecmp(arg, "basic"))
+			as -> output_format = OUTPUT_BASIC;
 		else if (!strcasecmp(arg, "raw"))
 			as -> output_format = OUTPUT_RAW;
 		else if (!strcasecmp(arg, "rawrel"))
 			as -> output_format = OUTPUT_RAWREL;
 		else if (!strcasecmp(arg, "obj"))
 			as -> output_format = OUTPUT_OBJ;
+		else if (!strcasecmp(arg, "srec"))
+			as -> output_format = OUTPUT_SREC;
+		else if (!strcasecmp(arg, "ihex"))
+			as -> output_format = OUTPUT_IHEX;
+		else if (!strcasecmp(arg, "hex"))
+			as -> output_format = OUTPUT_HEX;
 		else if (!strcasecmp(arg, "os9"))
 		{
 			as -> pragmas |= PRAGMA_DOLLARNOTLOCAL;
 			as -> output_format = OUTPUT_OS9;
 		}
+		else if (!strcasecmp(arg, "lwmod"))
+		{
+			as -> output_format = OUTPUT_LWMOD;
+		}
 		else
 		{
 			fprintf(stderr, "Invalid output format: %s\n", arg);
@@ -175,16 +236,20 @@
 		break;
 
 	case '9':
-		as -> target = TARGET_6809;
+		as -> pragmas |= PRAGMA_6809;
 		break;
 
 	case '3':
-		as -> target = TARGET_6309;
+		as -> pragmas &= ~PRAGMA_6809;
 		break;
 
 	case 'P':
 		as -> preprocess = 1;
 		break;
+	
+	case 0x200:
+		as -> pragmas |= PRAGMA_6800COMPAT;
+		break;
 		
 	case lw_cmdline_key_end:
 		break;
@@ -212,19 +277,21 @@
 main function; parse command line, set up assembler state, and run the 
 assembler on the first file
 */
-extern void do_pass1(asmstate_t *as);
-extern void do_pass2(asmstate_t *as);
-extern void do_pass3(asmstate_t *as);
-extern void do_pass4(asmstate_t *as);
-extern void do_pass5(asmstate_t *as);
-extern void do_pass6(asmstate_t *as);
-extern void do_pass7(asmstate_t *as);
-extern void do_output(asmstate_t *as);
-extern void do_list(asmstate_t *as);
-extern lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv);
-extern lw_expr_t lwasm_evaluate_var(char *var, void *priv);
-extern lw_expr_t lwasm_parse_term(char **p, void *priv);
-extern void lwasm_dividezero(void *priv);
+void do_pass1(asmstate_t *as);
+void do_pass2(asmstate_t *as);
+void do_pass3(asmstate_t *as);
+void do_pass4(asmstate_t *as);
+void do_pass5(asmstate_t *as);
+void do_pass6(asmstate_t *as);
+void do_pass7(asmstate_t *as);
+void do_output(asmstate_t *as);
+void do_symdump(asmstate_t *as);
+void do_list(asmstate_t *as);
+void do_map(asmstate_t *as);
+lw_expr_t lwasm_evaluate_special(int t, void *ptr, void *priv);
+lw_expr_t lwasm_evaluate_var(char *var, void *priv);
+lw_expr_t lwasm_parse_term(char **p, void *priv);
+void lwasm_dividezero(void *priv);
 
 struct passlist_s
 {
@@ -260,10 +327,18 @@
 	asmstate.include_list = lw_stringlist_create();
 	asmstate.input_files = lw_stringlist_create();
 	asmstate.nextcontext = 1;
-	asmstate.target = TARGET_6309;
+	asmstate.exprwidth = 16;
+	asmstate.tabwidth = 8;
+
+	// enable the "forward reference maximum size" pragma; old available
+	// can be obtained with --pragma=noforwardrefmax
+	asmstate.pragmas = PRAGMA_FORWARDREFMAX;
 	
 	/* parse command line arguments */	
-	lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, &asmstate);
+	if (lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, &asmstate) != 0)
+	{
+		exit(1);
+	}
 
 	if (!asmstate.output_file)
 	{
@@ -314,7 +389,7 @@
 			lw_free(n);
 		}
 	}	
-	else
+	else if ((asmstate.flags & FLAG_NOOUT) == 0)
 	{
 		debug_message(&asmstate, 50, "Doing output");
 		do_output(&asmstate);
@@ -327,6 +402,11 @@
 		debug_message(&asmstate, 50, "Invoking unicorns");
 		lwasm_do_unicorns(&asmstate);
 	}
+	do_symdump(&asmstate);
 	do_list(&asmstate);
+	do_map(&asmstate);
+
+	if (asmstate.testmode_errorcount > 0) exit(1);
+
 	exit(0);
 }
--- a/lwasm/os9.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/os9.c	Mon Aug 05 21:27:09 2019 -0600
@@ -38,7 +38,7 @@
 	
 	if (as -> output_format != OUTPUT_OS9 && as -> output_format != OUTPUT_OBJ)
 	{
-		lwasm_register_error(as, l, "os9 directive only valid for OS9 target");
+		lwasm_register_error2(as, l, E_DIRECTIVE_OS9_ONLY, "%s", "os9");
 		return;
 	}
 	
@@ -46,7 +46,7 @@
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 0, e);
@@ -70,14 +70,14 @@
 	
 	if (as -> output_format != OUTPUT_OS9)
 	{
-		lwasm_register_error(as, l,  "mod directive only valid for OS9 target");
+		lwasm_register_error2(as, l, E_DIRECTIVE_OS9_ONLY, "%s", "mod");
 		skip_operand(p);
 		return;
 	}
 	
 	if (as -> inmod)
 	{
-		lwasm_register_error(as, l,  "Already in a module!");
+		lwasm_register_error(as, l, E_MODULE_IN);
 		skip_operand(p);
 		return;
 	}
@@ -88,7 +88,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 
@@ -96,7 +96,7 @@
 
 		if (**p != ',')
 		{
-			lwasm_register_error(as, l, "Bad operand");
+			lwasm_register_error(as, l, E_OPERAND_BAD);
 			return;
 		}
 		(*p)++;
@@ -105,7 +105,7 @@
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	lwasm_save_expr(l, 5, e);
@@ -173,13 +173,13 @@
 	skip_operand(p);
 	if (as -> output_format != OUTPUT_OS9)
 	{
-		lwasm_register_error(as, l, "emod directive only valid for OS9 target");
+		lwasm_register_error2(as, l, E_DIRECTIVE_OS9_ONLY, "%s", "emod");
 		return;
 	}
 	
 	if (!(as -> inmod))
 	{
-		lwasm_register_error(as, l, "not in a module!");
+		lwasm_register_error(as, l, E_MODULE_NOTIN);
 		return;
 	}
 	
--- a/lwasm/output.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/output.c	Mon Aug 05 21:27:09 2019 -0600
@@ -23,7 +23,10 @@
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
-#include <unistd.h>
+
+#ifndef _MSC_VER
+#include <unistd.h>  // for unlink
+#endif
 
 #include <lw_alloc.h>
 #include <lw_expr.h>
@@ -32,9 +35,14 @@
 
 void write_code_raw(asmstate_t *as, FILE *of);
 void write_code_decb(asmstate_t *as, FILE *of);
+void write_code_BASIC(asmstate_t *as, FILE *of);
 void write_code_rawrel(asmstate_t *as, FILE *of);
 void write_code_obj(asmstate_t *as, FILE *of);
 void write_code_os9(asmstate_t *as, FILE *of);
+void write_code_hex(asmstate_t *as, FILE *of);
+void write_code_srec(asmstate_t *as, FILE *of);
+void write_code_ihex(asmstate_t *as, FILE *of);
+void write_code_lwmod(asmstate_t *as, FILE *of);
 
 // this prevents warnings about not using the return value of fwrite()
 // r++ prevents the "set but not used" warnings; should be optimized out
@@ -67,6 +75,10 @@
 	case OUTPUT_DECB:
 		write_code_decb(as, of);
 		break;
+	
+	case OUTPUT_BASIC:
+		write_code_BASIC(as, of);
+		break;
 		
 	case OUTPUT_RAWREL:
 		write_code_rawrel(as, of);
@@ -80,6 +92,22 @@
 		write_code_os9(as, of);
 		break;
 
+	case OUTPUT_HEX:
+		write_code_hex(as, of);
+		break;
+		
+	case OUTPUT_SREC:
+		write_code_srec(as, of);
+		break;
+
+	case OUTPUT_IHEX:
+		write_code_ihex(as, of);
+		break;
+
+	case OUTPUT_LWMOD:
+		write_code_lwmod(as, of);
+		break;
+
 	default:
 		fprintf(stderr, "BUG: unrecognized output format when generating output file\n");
 		fclose(of);
@@ -90,6 +118,106 @@
 	fclose(of);
 }
 
+int write_code_BASIC_fprintf(FILE *of, int linelength, int *linenumber, int value)
+{
+	if (linelength > 247)
+	{
+		fprintf(of, "\n");
+		linelength = fprintf(of, "%d DATA ", *linenumber);
+		*linenumber += 10;
+	}
+	else
+	{
+		linelength += fprintf(of, ",");
+	}
+	linelength += fprintf(of, "%d", value);
+
+	return linelength;
+}
+
+void write_code_BASIC(asmstate_t *as, FILE *of)
+{
+	line_t *cl;
+	line_t *startblock = as -> line_head;
+	line_t *endblock;
+	int linenumber, linelength, startaddress, lastaddress, address;
+	int outidx;
+	
+	fprintf(of, "10 READ A,B\n");
+	fprintf(of, "20 IF A=-1 THEN 70\n");
+	fprintf(of, "30 FOR C = A TO B\n");
+	fprintf(of, "40 READ D:POKE C,D\n");
+	fprintf(of, "50 NEXT C\n");
+	fprintf(of, "60 GOTO 10\n");
+	
+	if (as -> execaddr == 0)
+	{
+		fprintf(of, "70 END");
+	}
+	else
+	{
+		fprintf(of, "70 EXEC %d", as -> execaddr);
+	}
+	
+	linenumber = 80;
+	linelength = 255;
+	
+	while(startblock)
+	{
+		startaddress = -1;
+		endblock = NULL;
+		
+		for (cl = startblock; cl; cl = cl -> next)
+		{
+			if (cl -> outputl < 0)
+				continue;
+		
+			address = lw_expr_intval(cl -> addr);
+		
+			if (startaddress == -1)
+			{
+				startaddress = address;
+				lastaddress = address + cl -> outputl - 1;
+			}
+			else
+			{
+				if (lastaddress != address - 1)
+				{
+					endblock = cl;
+					break;
+				}
+				
+				lastaddress += cl -> outputl;
+			}
+		}
+	
+		if (startaddress != -1)
+		{
+			linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, startaddress);
+			linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, lastaddress);
+	
+			for (cl = startblock; cl != endblock; cl = cl -> next)
+			{
+				if (cl -> outputl < 0)
+					continue;
+		
+				for (outidx=0; outidx<cl -> outputl; outidx++)
+				{
+					linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, cl -> output[outidx]);
+				}
+			}
+		}
+	
+		startblock = cl;
+	}
+	
+	linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1);
+	linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1);
+	
+	fprintf(of, "\n");
+}
+
+
 /*
 rawrel output treats an ORG directive as an offset from the start of the
 file. Undefined results will occur if an ORG directive moves the output
@@ -219,6 +347,260 @@
 	writebytes(outbuf, 5, 1, of);
 }
 
+int fetch_output_byte(line_t *cl, char *value, int *addr)
+{
+	static int outidx = 0;
+	static int lastaddr = -2;
+	
+	// try to read next byte in current line's output field
+	if ((cl -> outputl > 0) && (outidx < cl -> outputl))
+	{
+		*addr = lw_expr_intval(cl -> addr) + outidx;
+		*value = *(cl -> output + outidx++);
+		
+		// this byte follows the previous byte (contiguous, rc = 1)
+		if (*addr == lastaddr + 1)
+		{
+			lastaddr = *addr;
+			return 1;
+		}
+		
+		// this byte does not follow prev byte (disjoint, rc = -1)
+		else 
+		{
+			lastaddr = *addr;
+			return -1;
+		}
+	}
+
+	// no (more) output from this line (rc = 0)
+	else
+	{
+		outidx = 0;
+		return 0;
+	}
+}
+
+
+/* a simple ASCII hex file format */
+
+void write_code_hex(asmstate_t *as, FILE *of)
+{
+	const int RECLEN = 16;
+	
+	line_t *cl;
+	char outbyte;
+	int outaddr;
+	int rc;
+	
+	for (cl = as -> line_head; cl; cl = cl -> next)
+		do
+		{
+			rc = fetch_output_byte(cl, &outbyte, &outaddr);
+			
+			// if address jump or xxx0 address, start new line
+			if ((rc == -1) || ((rc == 1) && (outaddr % RECLEN == 0)))
+			{
+				fprintf(of, "\r\n%04X:", (unsigned int)(outaddr & 0xffff));
+				fprintf(of, "%02X", (unsigned char)outbyte);
+				rc = -1;
+			}
+			if (rc == 1)
+				fprintf(of, ",%02X", (unsigned char)outbyte);
+		}
+		while (rc);
+}
+
+
+/* Motorola S19 hex file format */
+
+void write_code_srec(asmstate_t *as, FILE *of)
+{
+	#define SRECLEN 16
+	#define HDRLEN 51
+	
+	line_t *cl;
+	char outbyte;
+	int outaddr;
+	int rc;
+	unsigned int i;
+	int recaddr = 0;
+	unsigned int recdlen = 0;
+	unsigned char recdata[SRECLEN];
+	int recsum;
+	int reccnt = -1;
+	char rechdr[HDRLEN];
+	
+	for (cl = as -> line_head; cl; cl = cl -> next)
+		do
+		{
+			rc = fetch_output_byte(cl, &outbyte, &outaddr);
+			
+			// if address jump or xxx0 address, start new S1 record
+			if ((rc == -1) || ((rc == 1) && (outaddr % SRECLEN == 0)))
+			{
+				// if not already done so, emit an S0 header record
+				if (reccnt < 0)
+				{
+					// build header from version and filespec
+					// e.g. "[lwtools X.Y] filename.asm"
+					strcpy(rechdr, "[");
+					strcat(rechdr, PACKAGE_STRING);
+					strcat(rechdr, "] ");
+					i = strlen(rechdr);
+					strncat(rechdr, cl -> linespec, HDRLEN - 1 - i);
+					recsum = strlen(rechdr) + 3;
+					fprintf(of, "S0%02X0000", recsum);
+					for (i = 0; i < strlen(rechdr); i++)
+					{
+						fprintf(of, "%02X", (unsigned char)rechdr[i]);
+						recsum += (unsigned char)rechdr[i];
+					}
+					fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+					reccnt = 0;
+				}
+
+				// flush any current S1 record before starting new one
+				if (recdlen > 0)
+				{
+					recsum = recdlen + 3;
+					fprintf(of, "S1%02X%04X", recdlen + 3, recaddr & 0xffff);
+					for (i = 0; i < recdlen; i++)
+					{
+						fprintf(of, "%02X", (unsigned char)recdata[i]);
+						recsum += (unsigned char)recdata[i];
+					}
+					recsum += (recaddr >> 8) & 0xFF;
+					recsum += recaddr & 0xFF;
+					fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+					reccnt += 1;
+				}
+				
+				// now start the new S1 record
+				recdlen = 0;
+				recaddr = outaddr;
+				rc = 1;
+			}
+
+			// for each new byte read, add to recdata[]
+			if (rc == 1)
+				recdata[recdlen++] = outbyte;
+		}
+		while (rc);
+		
+	// done with all output lines, flush the final S1 record (if any)
+	if (recdlen > 0)
+	{
+		recsum = recdlen + 3;
+		fprintf(of, "S1%02X%04X", recdlen + 3, recaddr & 0xffff);
+		for (i = 0; i < recdlen; i++)
+		{
+			fprintf(of, "%02X", (unsigned char)recdata[i]);
+			recsum += (unsigned char)recdata[i];
+		}
+		recsum += (recaddr >> 8) & 0xFF;
+		recsum += recaddr & 0xFF;
+		fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+		reccnt += 1;
+	}
+
+	// if any S1 records were output, close with S5 and S9 records
+	if (reccnt > 0)
+	{
+		// emit S5 count record
+		recsum = 3;
+		recsum += (reccnt >> 8) & 0xFF;
+		recsum += reccnt & 0xFF;
+		fprintf(of, "S503%04X", (unsigned int)reccnt);
+		fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+		
+		// emit S9 end-of-file record
+		recsum = 3;
+		recsum += (as -> execaddr >> 8) & 0xFF;
+		recsum += (as -> execaddr) & 0xFF;
+		fprintf(of, "S903%04X", as -> execaddr & 0xffff);
+		fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+	}
+}
+
+
+/* Intel hex file format */
+
+void write_code_ihex(asmstate_t *as, FILE *of)
+{
+	#define IRECLEN 16
+	
+	line_t *cl;
+	char outbyte;
+	int outaddr;
+	int rc;
+	int i;
+	int recaddr = 0;
+	int recdlen = 0;
+	unsigned char recdata[IRECLEN];
+	int recsum;
+	int reccnt = 0;
+	
+	for (cl = as -> line_head; cl; cl = cl -> next)
+		do
+		{
+			rc = fetch_output_byte(cl, &outbyte, &outaddr);
+			
+			// if address jump or xxx0 address, start new ihx record
+			if ((rc == -1) || ((rc == 1) && (outaddr % IRECLEN == 0)))
+			{
+				// flush any current ihex record before starting new one
+				if (recdlen > 0)
+				{
+					recsum = recdlen;
+					fprintf(of, ":%02X%04X00", recdlen, recaddr & 0xffff);
+					for (i = 0; i < recdlen; i++)
+					{
+						fprintf(of, "%02X", (unsigned char)recdata[i]);
+						recsum += (unsigned char)recdata[i];
+					}
+					recsum += (recaddr >> 8) & 0xFF;
+					recsum += recaddr & 0xFF;
+					fprintf(of, "%02X\r\n", (unsigned char)(256 - recsum));
+					reccnt += 1;
+				}
+				
+				// now start the new ihex record
+				recdlen = 0;
+				recaddr = outaddr;
+				rc = 1;
+			}
+
+			// for each new byte read, add to recdata[]
+			if (rc == 1)
+				recdata[recdlen++] = outbyte;
+		}
+		while (rc);
+		
+	// done with all output lines, flush the final ihex record (if any)
+	if (recdlen > 0)
+	{
+		recsum = recdlen;
+		fprintf(of, ":%02X%04X00", recdlen, recaddr & 0xffff);
+		for (i = 0; i < recdlen; i++)
+		{
+			fprintf(of, "%02X", (unsigned char)recdata[i]);
+			recsum += (unsigned char)recdata[i];
+		}
+		recsum += (recaddr >> 8) & 0xFF;
+		recsum += recaddr & 0xFF;
+		fprintf(of, "%02X\r\n", (unsigned char)(256 - recsum));
+		reccnt += 1;
+	}
+
+	// if any ihex records were output, close with a "01" record
+	if (reccnt > 0)
+	{
+		fprintf(of, ":00%04X01FF", as -> execaddr & 0xffff);
+	}
+}
+	    
+	    
 void write_code_obj_sbadd(sectiontab_t *s, unsigned char b)
 {
 	if (s -> oblen >= s -> obsize)
@@ -623,3 +1005,241 @@
 	// the "" is NOT an error
 	writebytes("", 1, 1, of);
 }
+
+
+void write_code_lwmod(asmstate_t *as, FILE *of)
+{
+	line_t *l;
+	sectiontab_t *s;
+	reloctab_t *re;
+	int initsize, bsssize, mainsize, callsnum, namesize;
+	unsigned char *initcode, *maincode, *callscode, *namecode;
+	int relocsize;
+	unsigned char *reloccode;
+	int tsize, bssoff;
+	int initaddr = -1;
+
+	int i;
+	unsigned char buf[16];
+
+	// the magic number
+	buf[0] = 0x8f;
+	buf[1] = 0xcf;
+	
+	// run through the entire system and build the byte streams for each
+	// section; we will make sure we only have simple references for
+	// any undefined references. That means at most an ADD (or SUB) operation
+	// with a single BSS symbol reference and a single constant value.
+	// We will use the constant value in the code stream and record the
+	// offset in a separate code stream for the BSS relocation table.
+	
+	// We build everything in memory here because we need to calculate the
+	// sizes of everything before we can output the complete header.
+	
+	for (l = as -> line_head; l; l = l -> next)
+	{
+		if (l -> csect)
+		{
+			// we're in a section - need to output some bytes
+			if (l -> outputl > 0)
+				for (i = 0; i < l -> outputl; i++)
+					write_code_obj_sbadd(l -> csect, l -> output[i]);
+			else if (l -> outputl == 0 || l -> outputl == -1)
+				for (i = 0; i < l -> len; i++)
+					write_code_obj_sbadd(l -> csect, 0);
+		}
+	}
+	
+	// now run through sections and set various parameters
+	initsize = 0;
+	bsssize = 0;
+	mainsize = 0;
+	callsnum = 0;
+	callscode = NULL;
+	maincode = NULL;
+	initcode = NULL;
+	namecode = NULL;
+	namesize = 0;
+	relocsize = 0;
+	for (s = as -> sections; s; s = s -> next)
+	{
+		if (!strcmp(s -> name, "bss"))
+		{
+			bsssize = s -> oblen;
+		}
+		else if (!strcmp(s -> name, "main"))
+		{
+			maincode = s -> obytes;
+			mainsize = s -> oblen;
+		}
+		else if (!strcmp(s -> name, "init"))
+		{
+			initcode = s -> obytes;
+			initsize = s -> oblen;
+		}
+		else if (!strcmp(s -> name, "calls"))
+		{
+			callscode = s -> obytes;
+			callsnum = s -> oblen / 2;
+		}
+		else if (!strcmp(s -> name, "modname"))
+		{
+			namecode = s -> obytes;
+			namesize = 0;
+		}
+		for (re = s -> reloctab; re; re = re -> next)
+		{
+			if (re -> expr == NULL)
+				relocsize += 2;
+		}
+	}
+	if (namesize == 0)
+	{
+		namecode = (unsigned char *)(as -> output_file);
+	}
+	else
+	{
+		if (namecode[namesize - 1] != '\0')
+		{
+			namecode[namesize - 1] = '\0';
+		}
+		if (!*namecode)
+			namecode = (unsigned char *)(as -> output_file);
+	}
+	namesize = strlen((char *)namecode);
+
+	tsize = namesize + 1 + initsize + mainsize + callsnum * 2 + relocsize + 11;
+	bssoff = namesize + 1 + mainsize + callsnum * 2 + 11;
+	// set up section base addresses
+	for (s = as -> sections; s; s = s -> next)
+	{
+		if (!strcmp(s -> name, "main"))
+		{
+			s -> tbase = 11 + namesize + 1 + callsnum * 2;
+		}
+		else if (!strcmp(s -> name, "init"))
+		{
+			s -> tbase = bssoff + relocsize;
+		}
+		else if (!strcmp(s -> name, "calls"))
+		{
+			s -> tbase = 11;
+		}
+		else if (!strcmp(s -> name, "modname"))
+		{
+			s -> tbase = 11 + callsnum * 2;
+		}
+	}
+
+	// resolve the "init" address
+	if (as -> execaddr_expr)
+	{
+		// need to resolve address with proper section bases
+		lwasm_reduce_expr(as, as -> execaddr_expr);
+		initaddr = lw_expr_intval(as -> execaddr_expr);
+	}
+	else
+	{
+		initaddr = as -> execaddr;
+	}
+	
+	// build relocation data
+	reloccode = NULL;
+	if (relocsize)
+	{
+		unsigned char *tptr;
+		reloccode = lw_alloc(relocsize);
+		tptr = reloccode;
+		
+		for (s = as -> sections; s; s = s -> next)
+		{
+			for (re = s -> reloctab; re; re = re -> next)
+			{
+				lw_expr_t te;
+				line_t tl;
+				int offset;
+			
+				tl.as = as;
+				as -> cl = &tl;
+				as -> csect = s;
+//				as -> exportcheck = 1;
+
+				if (re -> expr)
+				{
+					int val;
+					int x;
+					
+					te = lw_expr_copy(re -> expr);
+					lwasm_reduce_expr(as, te);
+					if (!lw_expr_istype(te, lw_expr_type_int))
+					{
+						val = 0;
+					}
+					else
+					{
+						val = lw_expr_intval(te);
+					}
+					lw_expr_destroy(te);
+					x = s -> tbase;
+					s -> tbase = 0;
+					te = lw_expr_copy(re -> offset);
+					lwasm_reduce_expr(as, te);
+					offset = lw_expr_intval(te);
+					lw_expr_destroy(te);
+					s -> tbase = x;
+					// offset *should* be the offset in the section
+					s -> obytes[offset] = val >> 8;
+					s -> obytes[offset + 1] = val & 0xff;
+					continue;
+				}
+				
+				offset = 0;
+				te = lw_expr_copy(re -> offset);
+				lwasm_reduce_expr(as, te);
+				if (!lw_expr_istype(te, lw_expr_type_int))
+				{
+					lw_expr_destroy(te);
+					offset = 0;
+					continue;
+				}
+				offset = lw_expr_intval(te);
+				lw_expr_destroy(te);
+				//offset += sbase;
+				
+				*tptr++ = offset >> 8;
+				*tptr++ = offset & 0xff;
+			}
+		}
+	}
+
+	// total size
+	buf[2] = tsize >> 8;
+	buf[3] = tsize & 0xff;
+	// offset to BSS relocs
+	buf[4] = bssoff >> 8;
+	buf[5] = bssoff & 0xff;
+	// BSS size
+	buf[6] = bsssize >> 8;
+	buf[7] = bsssize & 0xff;
+	// init routine offset
+	buf[8] = initaddr >> 8;
+	buf[9] = initaddr & 0xff;
+	// number of call entries
+	buf[10] = callsnum;
+	// write the header
+	writebytes(buf, 11, 1, of);
+	// call data
+	if (callsnum)
+		writebytes(callscode, callsnum * 2, 1, of);
+	// module name
+	writebytes(namecode, namesize + 1, 1, of);
+	// main code
+	if (mainsize)
+		writebytes(maincode, mainsize, 1, of);
+	// bss relocs
+	if (relocsize)
+		writebytes(reloccode, relocsize, 1, of);
+	// init stuff
+	if (initsize)
+		writebytes(initcode, initsize, 1, of);
+}
--- a/lwasm/pass1.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass1.c	Mon Aug 05 21:27:09 2019 -0600
@@ -31,14 +31,14 @@
 #include "instab.h"
 #include "input.h"
 
-extern int expand_macro(asmstate_t *as, line_t *l, char **p, char *opc);
-extern int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc);
-extern int add_macro_line(asmstate_t *as, char *optr);
+int expand_macro(asmstate_t *as, line_t *l, char **p, char *opc);
+int expand_struct(asmstate_t *as, line_t *l, char **p, char *opc);
+int add_macro_line(asmstate_t *as, char *optr);
 
 /*
 pass 1: parse the lines
 
-line format:
+line format if PRAGMA_NEWSOURCE is not in force:
 
 [<symbol>] <opcode> <operand>[ <comment>]
 
@@ -48,6 +48,14 @@
 white space and must be followed by a single whitespace character. After
 that whitespace character, the line is parsed as if it had no line number.
 
+Also, no spaces are permitted within <operand>.
+
+With PRAGMA_NEWSOURCE in effect, line numbers are not allowed and there
+is no automatic comment at the end of each line. All comments must be
+introduced with the comment character. This allows the parser to handle
+spaces in operands unambiguously so in this mode, spaces are permitted
+within operands.
+
 */
 void do_pass1(asmstate_t *as)
 {
@@ -157,6 +165,7 @@
 			cl -> dpval = cl -> prev -> dpval;
 			
 		}
+		debug_message(as, 100, "Line pointer: %p", cl);
 		if (!lc && strcmp(cl -> linespec, cl -> prev -> linespec))
 			lc = 1;
 		if (lc)
@@ -174,12 +183,12 @@
 		}
 	
 		// skip comments
-		// commends do not create a context break
+		// comments do not create a context break
 		if (*line == '*' || *line == ';' || *line == '#')
 			goto nextline;
 
 		p1 = line;
-		if (isdigit(*p1))
+		if (isdigit(*p1) && !CURPRAGMA(cl, PRAGMA_NEWSOURCE))
 		{
 			// skip line number
 			while (*p1 && isdigit(*p1))
@@ -212,8 +221,6 @@
 		else
 			stspace = 0;
 
-//		if (*p1 == '*' || *p1 == ';' || *p1 == '#')
-//			goto nextline;
 		if (!*p1)
 		{
 			// nothing but whitespace - context break
@@ -235,7 +242,7 @@
 				p1++;
 			for (; *p1 && isspace(*p1); p1++)
 				/* do nothing */ ;
-			
+		
 			if (*p1 == '=')
 			{
 				tok = p1++;
@@ -263,6 +270,14 @@
 		}
 		if (*tok)
 		{
+			if (CURPRAGMA(cl, PRAGMA_TESTMODE))
+			{
+				/* in test mode, terminate the line here so we don't affect the parsers */
+				/* (cl -> ltext retains the full, unmodified string) */
+				char *t = strstr(p1, ";.");
+				if (t) *t = 0;
+			}
+
 			// look up operation code
 			lw_free(sym);
 			sym = lw_strndup(tok, p1 - tok);
@@ -271,11 +286,20 @@
 
 			for (opnum = 0; instab[opnum].opcode; opnum++)
 			{
+				// ignore 6800 compatibility opcodes unless asked for
+				if ((instab[opnum].flags & lwasm_insn_is6800) && !CURPRAGMA(cl, PRAGMA_6800COMPAT)) continue;
+				// ignore 6809 convenience opcodes unless asked for
+				if ((instab[opnum].flags & lwasm_insn_is6809conv) && !CURPRAGMA(cl, PRAGMA_6809CONV)) continue;
+				// ignore 6809 convenience opcodes in 6309 mode
+				if ((instab[opnum].flags & lwasm_insn_is6809conv) && !CURPRAGMA(cl, PRAGMA_6809)) continue;
+				// ignore 6309 convenience opcodes unless asked for
+				if ((instab[opnum].flags & lwasm_insn_is6309conv) && !CURPRAGMA(cl, PRAGMA_6309CONV)) continue;
+				// ignore emulator extension opcodes unless asked for
+				if ((instab[opnum].flags & lwasm_insn_isemuext) && !CURPRAGMA(cl, PRAGMA_EMUEXT)) continue;
+
 				if (!strcasecmp(instab[opnum].opcode, sym))
 					break;
 			}
-			if ((as -> target != TARGET_6309) && (instab[opnum].flags & lwasm_insn_is6309))
-				lwasm_register_error(as, cl, "Illegal use of 6309 instruction in 6809 mode (%s)", sym);
 			
 			// have to go to linedone here in case there was a symbol
 			// to register on this line
@@ -298,7 +322,7 @@
 			if (as -> skipcond && !(instab[opnum].flags & lwasm_insn_cond))
 				goto linedone;
         	
-        	if (!nomacro && (as -> pragmas & PRAGMA_SHADOW))
+			if (!nomacro && (as->pragmas & PRAGMA_SHADOW))
         	{
         		// check for macros even if they shadow real operations
         		// NOTE: "ENDM" cannot be shadowed
@@ -308,7 +332,11 @@
         			goto linedone;
         		}
         	}
-			if (instab[opnum].opcode == NULL)
+        	
+			if (instab[opnum].opcode == NULL ||
+				(CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6309)) ||
+				(!CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6809))
+			)
 			{
 				cl -> insn = -1;
 				if (*tok != ';' && *tok != '*')
@@ -321,7 +349,12 @@
 						if (expand_struct(as, cl, &p1, sym) != 0)
 						{
 							// structure expansion failed
-							lwasm_register_error(as, cl, "Bad opcode");
+							if (CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6309))
+								lwasm_register_error2(as, cl, E_6309_INVALID, "(%s)", sym);
+							else if (!CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6809))
+								lwasm_register_error2(as, cl, E_6809_INVALID, "(%s)", sym);
+							else
+								lwasm_register_error(as, cl, E_OPCODE_BAD);
 						}
 					}
 				}
@@ -332,14 +365,23 @@
 				// no parse func means operand doesn't matter
 				if (instab[opnum].parse)
 				{
+					if (CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6309))
+						lwasm_register_error2(as, cl, E_6309_INVALID, "(%s)", sym);
+					if (!CURPRAGMA(cl, PRAGMA_6809) && (instab[opnum].flags & lwasm_insn_is6809))
+						lwasm_register_error2(as, cl, E_6809_INVALID, "(%s)", sym);
+
 					if (as -> instruct == 0 || instab[opnum].flags & lwasm_insn_struct)
 					{
-						struct line_expr_s *le;
-
 						cl -> len = -1;
 						// call parse function
-					debug_message(as, 100, "len = %d, dlen = %d", cl -> len, cl -> dlen);
+						debug_message(as, 100, "len = %d, dlen = %d", cl -> len, cl -> dlen);
 						(instab[opnum].parse)(as, cl, &p1);
+
+						// if we're forcing address modes on pass 1, force a resolution
+						if (CURPRAGMA(cl, PRAGMA_FORWARDREFMAX) && instab[opnum].resolve)
+						{
+							(instab[opnum].resolve)(as, cl, 1);
+						}
 						if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
 						{
 							if (cl -> len == 0)
@@ -347,40 +389,31 @@
 							else
 								cl -> dlen = cl -> len;
 						}
-					
-						if (*p1 && !isspace(*p1) && !(cl -> err))
+						if (!CURPRAGMA(cl, PRAGMA_NEWSOURCE))
 						{
-							// flag bad operand error
-							lwasm_register_error(as, cl, "Bad operand (%s)", p1);
+							if (*p1 && !isspace(*p1) && !(cl -> err))
+							{
+								// flag bad operand error
+								lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1);
+							}
+						}
+						else
+						{
+							lwasm_skip_to_next_token(cl, &p1);
+							/* if we did not hit the end of the line and we aren't at a comment character, error out */
+							if (*p1 && *p1 != ';' && *p1 != '#' && *p1 != ';')
+							{
+								// flag bad operand error
+								lwasm_register_error2(as, cl, E_OPERAND_BAD, "%s", p1);
+							}
 						}
 						
 						/* do a reduction on the line expressions to avoid carrying excessive expression baggage if not needed */
-						as -> cl = cl;
-		
-						// simplify address
-						lwasm_reduce_expr(as, cl -> addr);
-		
-						// simplify each expression
-						for (le = cl -> exprs; le; le = le -> next)
-							lwasm_reduce_expr(as, le -> expr);
-						
-						/* try resolving the instruction as well */
-						if (cl -> insn >= 0 && instab[cl -> insn].resolve)
-						{
-							(instab[cl -> insn].resolve)(as, cl, 0);
-							if ((cl -> inmod == 0) && cl -> len >= 0 && cl -> dlen >= 0)
-							{
-								if (cl -> len == 0)
-									cl -> len = cl -> dlen;
-								else
-									cl -> dlen = cl -> len;
-							}
-						}
-
+						lwasm_reduce_line_exprs(cl);
 					}
 					else if (as -> instruct == 1)
 					{
-						lwasm_register_error(as, cl, "Bad operand (%s)", p1);
+						lwasm_register_error2(as, cl, E_OPERAND_BAD, "(%s)", p1);
 					}
 				}
 			}
@@ -399,7 +432,7 @@
 					if (!register_symbol(as, cl, cl -> sym, cl -> daddr, symbol_flag_none))
 					{
 						// symbol error
-						// lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym);
+						// lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", cl -> sym);
 					}
 				}
 				else
@@ -407,7 +440,7 @@
 					if (!register_symbol(as, cl, cl -> sym, cl -> addr, symbol_flag_none))
 					{
 						// symbol error
-						// lwasm_register_error(as, cl, "Bad symbol '%s'", cl -> sym);
+						// lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", cl -> sym);
 					}
 				}
 			}
@@ -415,7 +448,9 @@
 		}
 		if (as -> skipcond || as -> inmacro || cl -> ltext[0] == 1)
 			cl -> hideline = 1;
-			
+		if (as -> skipcond)
+			cl -> hidecond = 1;
+		
 	nextline:
 		if (sym)
 			lw_free(sym);
--- a/lwasm/pass2.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass2.c	Mon Aug 05 21:27:09 2019 -0600
@@ -67,7 +67,7 @@
 				else
 				{
 					// undefined export - register error
-					lwasm_register_error(as, ex -> line, "Undefined exported symbol");
+					lwasm_register_error(as, ex->line, E_SYMBOL_UNDEFINED_EXPORT);
 				}
 			}
 			ex -> se = s;
--- a/lwasm/pass4.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass4.c	Mon Aug 05 21:27:09 2019 -0600
@@ -85,7 +85,7 @@
 			debug_message(as, 200, "Try resolve = %d/%d", sl -> len, sl -> dlen);
 			if (force && sl -> len == -1 && sl -> dlen == -1)
 			{
-				lwasm_register_error(as, sl, "Instruction failed to resolve.");
+				lwasm_register_error(as, sl, E_INSTRUCTION_FAILED);
 				return;
 			}
 		}
--- a/lwasm/pass5.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass5.c	Mon Aug 05 21:27:09 2019 -0600
@@ -43,7 +43,7 @@
 		return 0;
 	if (lw_expr_istype(e, lw_expr_type_oper))
 		return 0;
-	if (lw_expr_istype(e, lw_expr_type_special) && as -> output_format == OUTPUT_OBJ)
+	if (lw_expr_istype(e, lw_expr_type_special) && (as -> output_format == OUTPUT_OBJ || as -> output_format == OUTPUT_LWMOD))
 	{
 		int t;
 		t = lw_expr_specint(e);
@@ -121,11 +121,11 @@
 		{
 			if (!exprok(as, cl -> addr))
 			{
-				lwasm_register_error(as, cl, "Cannot resolve line address");
+				lwasm_register_error(as, cl, E_LINE_ADDRESS);
 			}
 			if (!exprok(as, cl -> daddr))
 			{
-				lwasm_register_error(as, cl, "Cannot resolve line data address");
+				lwasm_register_error(as, cl, E_LINED_ADDRESS);
 			}
 		}
 	}
--- a/lwasm/pass6.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass6.c	Mon Aug 05 21:27:09 2019 -0600
@@ -46,11 +46,11 @@
 	if (lw_expr_istype(e, lw_expr_type_int))
 		return 0;
 	
-	if (as -> output_format == OUTPUT_OBJ)
+	if (as -> output_format == OUTPUT_OBJ || as -> output_format == OUTPUT_LWMOD)
 	{
 		if (lw_expr_istype(e, lw_expr_type_oper))
 			return 0;
-		if (lw_expr_istype(e, lw_expr_type_special) && as -> output_format == OUTPUT_OBJ)
+		if (lw_expr_istype(e, lw_expr_type_special) && (as -> output_format == OUTPUT_OBJ || as -> output_format == OUTPUT_LWMOD))
 		{
 			int t;
 			t = lw_expr_specint(e);
@@ -83,7 +83,7 @@
 			lwasm_reduce_expr(as, le -> expr);
 			if (!exprok(as, le -> expr))
 			{
-				lwasm_register_error(as, cl, "Invalid expression: %s", lw_expr_print(le -> expr));
+				lwasm_register_error2(as, cl, E_EXPRESSION_BAD, "%s", lw_expr_print(le -> expr));
 			}
 		}
 	}
--- a/lwasm/pass7.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pass7.c	Mon Aug 05 21:27:09 2019 -0600
@@ -46,6 +46,30 @@
 			{
 				(instab[cl -> insn].emit)(as, cl);
 			}
+
+			if (CURPRAGMA(cl, PRAGMA_TESTMODE))
+			{
+				char* buf;
+				int len;
+				lwasm_testflags_t flags;
+				lwasm_errorcode_t err;
+
+				lwasm_parse_testmode_comment(cl, &flags, &err, &len, &buf);
+
+				if (flags == TF_ERROR && cl -> err_testmode == 0)
+				{
+					char s[128];
+					sprintf(s, "expected %d but assembled OK", err);
+					lwasm_error_testmode(cl, s, 0);
+				}
+
+				if (flags == TF_EMIT)
+				{
+					if (cl -> len != len) lwasm_error_testmode(cl, "incorrect assembly (wrong length)", 0);
+					if (memcmp(buf, cl -> output, len) != 0) lwasm_error_testmode(cl, "incorrect assembly", 0);
+					lw_free(buf);
+				}
+			}
 		}
 	}
 }
--- a/lwasm/pragma.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pragma.c	Mon Aug 05 21:27:09 2019 -0600
@@ -60,43 +60,72 @@
 	{ "symbolnocase", "nosymbolnocase", PRAGMA_SYMBOLNOCASE },
 	{ "nosymbolcase", "symbolcase", PRAGMA_SYMBOLNOCASE },
 	{ "condundefzero", "nocondundefzero", PRAGMA_CONDUNDEFZERO },
-	{ 0, 0, 0}
+	{ "6809", "6309", PRAGMA_6809 },
+	{ "6800compat", "no6800compat", PRAGMA_6800COMPAT },
+	{ "forwardrefmax", "noforwardrefmax", PRAGMA_FORWARDREFMAX },
+	{ "testmode", "notestmode", PRAGMA_TESTMODE },
+	{ "c", "noc", PRAGMA_C },
+	{ "cc", "nocc", PRAGMA_CC },
+	{ "cd", "nocd", PRAGMA_CD },
+	{ "ct", "noct", PRAGMA_CT },
+	{ "qrts", "noqrts", PRAGMA_QRTS },
+	{ "m80ext", "nom80ext", PRAGMA_M80EXT },
+	{ "6809conv", "no6809conv", PRAGMA_6809CONV },
+	{ "6309conv", "no6309conv", PRAGMA_6309CONV },
+	{ "newsource", "nonewsource", PRAGMA_NEWSOURCE },
+	{ "nooldsource", "oldsource", PRAGMA_NEWSOURCE },
+	{ "operandsizewarning", "nooperandsizewarning", PRAGMA_OPERANDSIZE },
+	{ "emuext", "noemuext", PRAGMA_EMUEXT },
+	{ "nooutput", "output", PRAGMA_NOOUTPUT },
+	{ "noexpandcond", "expandcond", PRAGMA_NOEXPANDCOND },
+	{ 0, 0, 0 }
 };
 
+int parse_pragma_helper(char *p)
+{
+	int i;
+
+	for (i = 0; set_pragmas[i].setstr; i++)
+	{
+		if (!strcasecmp(p, set_pragmas[i].setstr))
+		{
+			return set_pragmas[i].flag;
+			return 1;
+		}
+		if (!strcasecmp(p, set_pragmas[i].resetstr))
+		{
+			return set_pragmas[i].flag | PRAGMA_CLEARBIT;
+			return 2;
+		}
+	}
+
+	return 0;
+}
+
 int parse_pragma_string(asmstate_t *as, char *str, int ignoreerr)
 {
 	char *p;
-	int i;
 	const char *np = str;
-	int pragmas = as -> pragmas;
+	int pragma;
 
 	while (np)
 	{
 		p = lw_token(np, ',', &np);
-		debug_message(as, 200, "Setting pragma %s", p);
-		for (i = 0; set_pragmas[i].setstr; i++)
-		{
-			if (!strcasecmp(p, set_pragmas[i].setstr))
-			{
-				pragmas |= set_pragmas[i].flag;
-				goto out;
-			}
-			if (!strcasecmp(p, set_pragmas[i].resetstr))
-			{
-				pragmas &= ~(set_pragmas[i].flag);
-				goto out;
-			}
-		}
-		/* unrecognized pragma here */
-		if (!ignoreerr)
-		{
-			lw_free(p);
+		debug_message(as, 200, "Setting/resetting pragma %s", p);
+		pragma = parse_pragma_helper(p);
+		debug_message(as, 200, "Got pragma code %08X", pragma);
+		lw_free(p);
+
+		if (pragma == 0 && !ignoreerr)
 			return 0;
-		}
-	out:	
-		lw_free(p);
+
+		if (pragma & PRAGMA_CLEARBIT)
+			as->pragmas &= ~pragma;
+		else
+			as->pragmas |= pragma;
+		
+		debug_message(as, 200, "New pragma state: %08X", as -> pragmas);
 	}
-	as -> pragmas = pragmas;
 	return 1;
 }
 
@@ -114,10 +143,15 @@
 
 	if (parse_pragma_string(as, ps, 0) == 0)
 	{
-		lwasm_register_error(as, l, "Unrecognized pragma string");
+		lwasm_register_error(as, l, E_PRAGMA_UNRECOGNIZED);
 	}
 	if (as -> pragmas & PRAGMA_NOLIST)
 		l -> pragmas |= PRAGMA_NOLIST;
+	if (as->pragmas & PRAGMA_CC)
+	{
+		l->pragmas |= PRAGMA_CC;
+		as->pragmas &= ~PRAGMA_CC;
+	}
 	lw_free(ps);
 }
 
@@ -137,6 +171,11 @@
 	parse_pragma_string(as, ps, 1);
 	if (as -> pragmas & PRAGMA_NOLIST)
 		l -> pragmas |= PRAGMA_NOLIST;
+	if (as->pragmas & PRAGMA_CC)
+	{
+		l->pragmas |= PRAGMA_CC;
+		as->pragmas &= ~PRAGMA_CC;
+	}
 	lw_free(ps);
 }
 
--- a/lwasm/pseudo.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/pseudo.c	Mon Aug 05 21:27:09 2019 -0600
@@ -19,6 +19,8 @@
 
 */
 
+#include "lwasm.h"
+
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
@@ -27,13 +29,12 @@
 
 #include <lw_alloc.h>
 
-#include "lwasm.h"
 #include "instab.h"
 #include "input.h"
 
 #include "lw_string.h"
 
-extern void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss);
+void register_struct_entry(asmstate_t *as, line_t *l, int size, structtab_t *ss);
 
 // for "dts"
 PARSEFUNC(pseudo_parse_dts)
@@ -94,10 +95,14 @@
 {
 	lw_expr_t addr;
 	
-	as -> endseen = 1;
 	l -> len = 0;
-	
-	if (as -> output_format != OUTPUT_DECB)
+
+	if (CURPRAGMA(l, PRAGMA_M80EXT) && input_isinclude(as))
+		return;	/* ignore END inside includes */
+
+	as->endseen = 1;
+
+	if ((as -> output_format != OUTPUT_DECB) && (as -> output_format != OUTPUT_BASIC) && (as -> output_format != OUTPUT_LWMOD && (as -> output_format != OUTPUT_IHEX) && (as -> output_format != OUTPUT_SREC)))
 	{
 		skip_operand(p);
 		return;
@@ -113,7 +118,7 @@
 	}
 	if (!addr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, as->cl, E_EXPRESSION_BAD);
 		addr = lw_expr_build(lw_expr_type_int, 0);
 	}
 	lwasm_save_expr(l, 0, addr);
@@ -122,15 +127,30 @@
 EMITFUNC(pseudo_emit_end)
 {
 	lw_expr_t addr;
-	
+
+	if (CURPRAGMA(l, PRAGMA_M80EXT) && input_isinclude(as))
+		return;	/* ignore END inside includes */
+
 	addr = lwasm_fetch_expr(l, 0);
 	
 	if (addr)
 	{
 		if (!lw_expr_istype(addr, lw_expr_type_int))
-			lwasm_register_error(as, l, "Exec address not constant!");
+		{
+			if (as -> output_format == OUTPUT_LWMOD)
+			{
+				as -> execaddr_expr = lw_expr_copy(addr);
+			}
+			else
+			{
+				lwasm_register_error(as, l, E_EXEC_ADDRESS);
+			}
+		}
 		else
+		{
+			as -> execaddr_expr = NULL;
 			as -> execaddr = lw_expr_intval(addr);
+		}
 	}
 	as -> endseen = 1;
 }
@@ -145,7 +165,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad expression (#%d)", i);
+			lwasm_register_error2(as, l, E_EXPRESSION_BAD, "(#%d)", i);
 			break;
 		}
 		lwasm_save_expr(l, i++, e);
@@ -180,7 +200,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad expression (#%d)", i);
+			lwasm_register_error2(as, l, E_EXPRESSION_BAD, "(#%d)", i);
 			break;
 		}
 		lwasm_save_expr(l, i++, e);
@@ -215,7 +235,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad expression (#%d)", i);
+			lwasm_register_error2(as, l, E_EXPRESSION_BAD, "(#%d)", i);
 			break;
 		}
 		lwasm_save_expr(l, i++, e);
@@ -258,7 +278,7 @@
 		e = lwasm_parse_expr(as, p);
 		if (!e)
 		{
-			lwasm_register_error(as, l, "Bad expression (#%d)", i);
+			lwasm_register_error2(as, l, E_EXPRESSION_BAD, "(#%d)", i);
 			break;
 		}
 		lwasm_save_expr(l, i++, e);
@@ -298,7 +318,7 @@
 			if (blen >= bsize)
 			{
 				str = lw_realloc(str, bsize + 32);
-				bsize++;
+				bsize += 32;
 			}
 			str[blen++] = **p;
 		}
@@ -421,41 +441,7 @@
 	
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Bad operand");
-		return;
-	}
-	
-	delim = **p;
-	(*p)++;
-	
-	
-	i = cstringlen(as, l, p, delim);
-	
-	if (**p != delim)
-	{
-		lwasm_register_error(as, l, "Bad operand");
-		return;
-	}
-	(*p)++;	
-	l -> len = i;
-}
-
-EMITFUNC(pseudo_emit_fcc)
-{
-	int i;
-	
-	for (i = 0; i < l -> len; i++)
-		lwasm_emit(l, l -> lstr[i]);
-}
-
-PARSEFUNC(pseudo_parse_fcs)
-{
-	char delim;
-	int i;
-	
-	if (!**p)
-	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -466,7 +452,60 @@
 	
 	if (**p != delim)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
+		return;
+	}
+	(*p)++;	
+	l -> len = i;
+
+	/* handle additional expressions, like FCC "Hello",13,0 */
+	if (CURPRAGMA(l, PRAGMA_M80EXT))
+	{
+		if (**p == ',')
+		{
+			(*p)++;
+			pseudo_parse_fcb(as, l, p);
+			l -> fcc_extras = l -> len;
+			l -> len = i + l -> fcc_extras;
+		}
+	}
+}
+
+EMITFUNC(pseudo_emit_fcc)
+{
+	int i;
+	lw_expr_t e;
+
+	for (i = 0; i < l -> len - l -> fcc_extras; i++)
+		lwasm_emit(l, l -> lstr[i]);
+
+	/* PRAGMA_M80EXT */
+	for (i = 0; i < l -> fcc_extras; i++)
+	{
+		e = lwasm_fetch_expr(l, i);
+		lwasm_emitexpr(l, e, 1);
+	}
+}
+
+PARSEFUNC(pseudo_parse_fcs)
+{
+	char delim;
+	int i;
+	
+	if (!**p)
+	{
+		lwasm_register_error(as, l, E_OPERAND_BAD);
+		return;
+	}
+	
+	delim = **p;
+	(*p)++;
+	
+	i = cstringlen(as, l, p, delim);
+	
+	if (**p != delim)
+	{
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	(*p)++;
@@ -489,7 +528,7 @@
 	
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -500,7 +539,7 @@
 
 	if (**p != delim)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	(*p)++;
@@ -523,7 +562,7 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 
 	l -> lint = 0;
@@ -532,7 +571,7 @@
 		lwasm_reduce_expr(as, expr);
 		if (!lw_expr_istype(expr, lw_expr_type_int))
 		{
-			lwasm_register_error(as, l, "Expression must be constant at parse time");
+			lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		}
 		else
 		{
@@ -579,7 +618,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative reservation sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_RESERVATION, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			l -> dlen = 0;
 			return;
@@ -597,7 +636,7 @@
 		return;
 
 	if (l -> len < 0 || l -> dlen < 0)
-		lwasm_register_error(as, l, "Expression not constant: %d %d", l -> len, l -> dlen);
+		lwasm_register_error2(as, l, E_EXPRESSION_NOT_CONST, "%d %d", l -> len, l -> dlen);
 }
 
 PARSEFUNC(pseudo_parse_rmd)
@@ -608,7 +647,7 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 	
 	if (as -> instruct)
@@ -616,7 +655,7 @@
 		lwasm_reduce_expr(as, expr);
 		if (!lw_expr_istype(expr, lw_expr_type_int))
 		{
-			lwasm_register_error(as, l, "Expression must be constant at parse time");
+			lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		}
 		else
 		{
@@ -663,7 +702,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative reservation sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_RESERVATION, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			l -> dlen = 0;
 			return;
@@ -681,7 +720,7 @@
 		return;
 
 	if (l -> len < 0 || l -> dlen < 0)
-		lwasm_register_error(as, l, "Expression not constant");
+		lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 }
 
 
@@ -693,14 +732,14 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 	if (as -> instruct)
 	{
 		lwasm_reduce_expr(as, expr);
 		if (!lw_expr_istype(expr, lw_expr_type_int))
 		{
-			lwasm_register_error(as, l, "Expression must be constant at parse time");
+			lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		}
 		else
 		{
@@ -747,7 +786,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative reservation sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_RESERVATION, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			l -> dlen = 0;
 			return;
@@ -765,7 +804,7 @@
 		return;
 
 	if (l -> len < 0 || l -> dlen < 0)
-		lwasm_register_error(as, l, "Expression not constant");
+		lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 }
 
 
@@ -776,7 +815,7 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 	
 	lwasm_save_expr(l, 0, expr);
@@ -795,7 +834,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative block sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_BLOCKSIZE, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			return;
 		}
@@ -809,7 +848,7 @@
 
 	if (l -> len < 0)
 	{
-		lwasm_register_error(as, l, "Expression not constant");
+		lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		return;
 	}
 
@@ -825,7 +864,7 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 	
 	lwasm_save_expr(l, 0, expr);
@@ -844,7 +883,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative block sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_BLOCKSIZE, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			return;
 		}
@@ -858,7 +897,7 @@
 
 	if (l -> len < 0)
 	{
-		lwasm_register_error(as, l, "Expression not constant");
+		lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		return;
 	}
 
@@ -873,7 +912,7 @@
 	expr = lwasm_parse_expr(as, p);
 	if (!expr)
 	{
-		lwasm_register_error(as, l, "Bad expression");
+		lwasm_register_error(as, l, E_EXPRESSION_BAD);
 	}
 	
 	lwasm_save_expr(l, 0, expr);
@@ -892,7 +931,7 @@
 	{
 		if (lw_expr_intval(expr) < 0)
 		{
-			lwasm_register_error(as, l, "Negative block sizes make no sense! (%d)", lw_expr_intval(expr));
+			lwasm_register_error2(as, l, E_NEGATIVE_BLOCKSIZE, "(%d)", lw_expr_intval(expr));
 			l -> len = 0;
 			return;
 		}
@@ -906,7 +945,7 @@
 
 	if (l -> len < 0)
 	{
-		lwasm_register_error(as, l, "Expression not constant");
+		lwasm_register_error(as, l, E_EXPRESSION_NOT_CONST);
 		return;
 	}
 
@@ -923,7 +962,7 @@
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -938,6 +977,44 @@
 	l -> len = 0;
 }
 
+PARSEFUNC(pseudo_parse_reorg)
+{
+	lw_expr_t e = NULL;
+
+	l -> len = 0;
+
+	line_t *cl = l;
+	for (cl = cl -> prev; cl; cl = cl -> prev)
+	{
+		if (cl -> insn == -1) continue;
+
+		if (!strcmp("org", instab[cl -> insn].opcode))
+		{
+			if (cl -> prev)
+			{
+				e = lw_expr_copy(cl -> prev -> daddr);
+				break;
+			}
+		}
+	}
+
+	if (!e)
+	{
+		lwasm_register_error(as, l, E_ORG_NOT_FOUND);
+		return;
+	}
+
+	lw_expr_destroy(l -> daddr);
+	l -> daddr = e;
+
+	if (l -> inmod == 0)
+	{
+		lw_expr_destroy(l -> addr);
+		l -> addr = e;
+	}
+	l -> len = 0;
+}
+
 PARSEFUNC(pseudo_parse_equ)
 {
 	lw_expr_t e;
@@ -946,14 +1023,14 @@
 	
 	if (!(l -> sym))
 	{
-		lwasm_register_error(as, l, "Missing symbol");
+		lwasm_register_error(as, l, E_SYMBOL_MISSING);
 		return;
 	}
 	
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -971,14 +1048,14 @@
 	
 	if (!(l -> sym))
 	{
-		lwasm_register_error(as, l, "Missing symbol");
+		lwasm_register_error(as, l, E_SYMBOL_MISSING);
 		return;
 	}
 	
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -996,14 +1073,14 @@
 	
 	if (as -> output_format == OUTPUT_OBJ)
 	{
-		lwasm_register_error(as, l, "SETDP not permitted for object target");
+		lwasm_register_error(as, l, E_SETDP_INVALID);
 		return;
 	}
 	
 	e = lwasm_parse_expr(as, p);
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -1011,7 +1088,7 @@
 	lwasm_reduce_expr(as, e);
 	if (!lw_expr_istype(e, lw_expr_type_int))
 	{
-		lwasm_register_error(as, l, "SETDP must be constant on pass 1");
+		lwasm_register_error(as, l, E_SETDP_NOT_CONST);
 		lw_expr_destroy(e);
 		return;
 	}
@@ -1025,6 +1102,23 @@
 {
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
+
+	if (as -> skipcond && !(as -> skipmacro))
+	{
+		as -> skipcount++;
+		skip_operand(p);
+		return;
+	}
+	
+	lwasm_register_error2(as, l, W_NOT_SUPPORTED, "%s", "IFP1");
+}
+
+PARSEFUNC(pseudo_parse_ifp2)
+{
+	l -> len = 0;
+	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1033,23 +1127,7 @@
 		return;
 	}
 	
-	lwasm_register_warning(as, l, "IFP1 if is not supported; ignoring");
-	
-}
-
-PARSEFUNC(pseudo_parse_ifp2)
-{
-	l -> len = 0;
-	l -> hideline = 1;
-	
-	if (as -> skipcond && !(as -> skipmacro))
-	{
-		as -> skipcount++;
-		skip_operand(p);
-		return;
-	}
-	
-	lwasm_register_warning(as, l, "IFP2 if is not supported; ignoring");
+	lwasm_register_error2(as, l, W_NOT_SUPPORTED, "%s", "IFP2");
 }
 
 PARSEFUNC(pseudo_parse_ifeq)
@@ -1058,6 +1136,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1082,6 +1161,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1107,6 +1187,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1131,6 +1212,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1155,6 +1237,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1178,6 +1261,8 @@
 	lw_expr_t e;
 
 	l -> hideline = 1;
+	l -> hidecond = 1;
+
 	l -> len = 0;
 	
 	if (as -> skipcond && !(as -> skipmacro))
@@ -1200,6 +1285,8 @@
 PARSEFUNC(pseudo_parse_endc)
 {
 	l -> hideline = 1;
+	l -> hidecond = 1;
+
 	l -> len = 0;
 	skip_operand(p);
 	if (as -> skipcond && !(as -> skipmacro))
@@ -1213,6 +1300,7 @@
 PARSEFUNC(pseudo_parse_else)
 {
 	l -> len = 0;
+	l -> hidecond = 1;
 	l -> hideline = 1;
 	skip_operand(p);
 	
@@ -1240,6 +1328,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1280,6 +1369,7 @@
 	
 	l -> len = 0;
 	l -> hideline = 1;
+	l -> hidecond = 1;
 	
 	if (as -> skipcond && !(as -> skipmacro))
 	{
@@ -1305,15 +1395,68 @@
 	}
 }
 
+PARSEFUNC(pseudo_parse_ifpragma)
+{
+	char *pstr;
+	int i;
+	int pragma;
+	int compare;
+
+	l -> len = 0;
+	l -> hideline = 1;
+	l -> hidecond = 1;
+
+	if (as -> skipcond && !(as -> skipmacro))
+	{
+		as -> skipcount++;
+		skip_operand(p);
+		return;
+	}
+
+again:
+	for (i = 0; (*p)[i] && !isspace((*p)[i]) && (*p)[i] != '|' && (*p)[i] != '&'; i++)
+		/* do nothing */;
+
+	pstr = lw_strndup(*p, i);
+	(*p) += i;
+
+	pragma = parse_pragma_helper(pstr);
+	if (!pragma) lwasm_register_error(as, l, E_PRAGMA_UNRECOGNIZED);
+
+	lw_free(pstr);
+
+	if (pragma & PRAGMA_CLEARBIT)
+	{
+		pragma &= ~PRAGMA_CLEARBIT;			/* strip off flag bit */
+		compare = l -> pragmas & pragma ? 0 : 1;
+	}
+	else
+	{
+		compare = l -> pragmas & pragma;
+	}
+
+	if (!compare)
+	{
+		if (**p == '|')
+		{
+			(*p)++;
+			goto again;
+		}
+		as -> skipcond = 1;
+		as -> skipcount = 1;
+	}
+	skip_operand(p);
+}
+
 PARSEFUNC(pseudo_parse_error)
 {
-	lwasm_register_error(as, l, "User error: %s", *p);
+	lwasm_register_error2(as, l, E_USER_SPECIFIED, "%s", *p);
 	skip_operand(p);
 }
 
 PARSEFUNC(pseudo_parse_warning)
 {
-	lwasm_register_warning(as, l, "User warning: %s", *p);
+	lwasm_register_error2(as, l, W_USER_SPECIFIED, "%s", *p);
 	l -> len = 0;
 	skip_operand(p);
 }
@@ -1328,7 +1471,7 @@
 	
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Missing filename");
+		lwasm_register_error(as, l, E_FILENAME_MISSING);
 		return;
 	}
 	
@@ -1353,7 +1496,7 @@
 	fp = input_open_standalone(as, fn, &rfn);
 	if (!fp)
 	{
-		lwasm_register_error(as, l, "Cannot open file");
+		lwasm_register_error(as, l, E_FILE_OPEN);
 		lw_free(fn);
 		return;
 	}
@@ -1372,10 +1515,10 @@
 	FILE *fp;
 	int c;
 	
-	fp = fopen(l -> lstr, "r");
+	fp = fopen(l -> lstr, "rb");
 	if (!fp)
 	{
-		lwasm_register_error(as, l, "Cannot open file (emit)!");
+		lwasm_register_error2(as, l, E_FILE_OPEN, "%s", "(emit)!");
 		return;
 	}
 	
@@ -1401,7 +1544,7 @@
 		
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Missing filename");
+		lwasm_register_error(as, l, E_FILENAME_MISSING);
 		return;
 	}
 	
@@ -1445,7 +1588,7 @@
 	lw_expr_t e;
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -1453,7 +1596,7 @@
 	
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -1470,7 +1613,7 @@
 	}
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad padding");
+		lwasm_register_error(as, l, E_PADDING_BAD);
 		return;
 	}
 	
@@ -1491,7 +1634,7 @@
 		align = lw_expr_intval(e);
 		if (align < 1)
 		{
-			lwasm_register_error(as, l, "Invalid alignment");
+			lwasm_register_error(as, l, E_ALIGNMENT_INVALID);
 			return;
 		}
 	}
@@ -1547,14 +1690,14 @@
 	lw_expr_t e, e1;
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
 	e1 = lwasm_parse_expr(as, p);
 	if (**p != ',')
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	(*p)++;
@@ -1562,7 +1705,7 @@
 	
 	if (!e)
 	{
-		lwasm_register_error(as, l, "Bad operand");
+		lwasm_register_error(as, l, E_OPERAND_BAD);
 		return;
 	}
 	
@@ -1571,7 +1714,7 @@
 
 	if (!e1)
 	{
-		lwasm_register_error(as, l, "Bad padding");
+		lwasm_register_error(as, l, E_PADDING_BAD);
 		return;
 	}
 }
@@ -1594,7 +1737,7 @@
 		if (align < 0)
 		{
 			lw_expr_destroy(te);
-			lwasm_register_error(as, l, "Invalid fill length");
+			lwasm_register_error(as, l, E_FILL_INVALID);
 			return;
 		}
 	}
@@ -1770,7 +1913,7 @@
 	char *arg0;
 	char *arg1;
 	char *arg2;
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1796,7 +1939,7 @@
 	char *arg0;
 	char *arg1;
 	char *arg2;
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1822,7 +1965,7 @@
 	char *arg0;
 	char *arg1;
 	char *arg2;
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1848,7 +1991,7 @@
 	char *arg0;
 	char *arg1;
 	char *arg2;
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1877,7 +2020,7 @@
 	char *rarg1;
 	char *rarg2;
 	
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1912,7 +2055,7 @@
 	char *rarg1;
 	char *rarg2;
 	
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1949,7 +2092,7 @@
 	char *rarg1;
 	char *rarg2;
 	
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -1985,7 +2128,7 @@
 	char *rarg1;
 	char *rarg2;
 	
-	int plen;
+	size_t plen;
 	int c = 0;
 	
 	arg0 = strcond_parsearg(p);
@@ -2051,7 +2194,7 @@
 	tstr = strcond_parsearg(p);
 	if (!**p || isspace(**p))	
 	{
-		lwasm_register_error(as, l, "Bad string condition");
+		lwasm_register_error(as, l, E_STRING_BAD);
 		return;
 	}
 		
@@ -2063,7 +2206,7 @@
 	
 	if (strops[strop].str == NULL)
 	{
-		lwasm_register_error(as, l, "Bad string condition");
+		lwasm_register_error(as, l, E_STRING_BAD);
 	}
 
 	tv = (*(strops[strop].fn))(p);
--- a/lwasm/section.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/section.c	Mon Aug 05 21:27:09 2019 -0600
@@ -35,15 +35,15 @@
 	char *opts = NULL;
 	sectiontab_t *s;
 
-	if (as -> output_format != OUTPUT_OBJ)
+	if (as -> output_format != OUTPUT_OBJ && as -> output_format != OUTPUT_LWMOD)
 	{
-		lwasm_register_error(as, l, "Cannot use sections unless using the object target");
+		lwasm_register_error(as, l, E_SECTION_TARGET);
 		return;
 	}
 	
 	if (!**p)
 	{
-		lwasm_register_error(as, l, "Need section name");
+		lwasm_register_error(as, l, E_SECTION_NAME);
 		return;
 	}
 
@@ -62,7 +62,7 @@
 	sn = lw_strndup(*p, p2 - *p);
 	*p = p2;
 	
-	if (**p == ',')
+	if (**p == ',' && as -> output_format != OUTPUT_LWMOD)
 	{
 		// have opts
 		(*p)++;
@@ -74,6 +74,20 @@
 		*p = p2;
 	}
 
+	if (as -> output_format == OUTPUT_LWMOD)
+	{
+		for (p2 = sn; *p2; p2++)
+			*p2 = tolower(*p2);
+		
+		if (strcmp(sn, "bss") && strcmp(sn, "main") && strcmp(sn, "init") && strcmp(sn, "calls") && strcmp(sn, "modname"))
+		{
+			lwasm_register_error(as, l, E_SECTION_NAME);
+			lw_free(sn);
+			lw_free(opts);
+			return;
+		}
+	}
+
 	for (s = as -> sections; s; s = s -> next)
 	{
 		if (!strcmp(s -> name, sn))
@@ -81,7 +95,7 @@
 	}
 	if (s && opts)
 	{
-		lwasm_register_warning(as, l, "Section flags can only be specified the first time; ignoring duplicate definition");
+		lwasm_register_error(as, l, W_DUPLICATE_SECTION);
 	}
 	if (!s)
 	{
@@ -90,6 +104,7 @@
 		s -> oblen = 0;
 		s -> obsize = 0;
 		s -> obytes = NULL;
+		s -> tbase = -1;
 		s -> name = lw_strdup(sn);
 		s -> offset = lw_expr_build(lw_expr_type_special, lwasm_expr_secbase, s);
 		s -> flags = section_flag_none;
@@ -125,7 +140,7 @@
 			}
 			else
 			{
-				lwasm_register_error(as, l, "Unrecognized section flag");
+				lwasm_register_error(as, l, E_SECTION_FLAG);
 				lw_free(sn);
 				lw_free(opts);
 				lw_free(s -> name);
@@ -156,9 +171,9 @@
 
 PARSEFUNC(pseudo_parse_endsection)
 {
-	if (as -> output_format != OUTPUT_OBJ)
+	if (as -> output_format != OUTPUT_OBJ && as -> output_format != OUTPUT_LWMOD)
 	{
-		lwasm_register_error(as, l, "Cannot use sections unless using the object target");
+		lwasm_register_error(as, l, E_SECTION_TARGET);
 		return;
 	}
 
@@ -166,7 +181,7 @@
 
 	if (!(as -> csect))
 	{
-		lwasm_register_error(as, l, "ENDSECTION without SECTION");
+		lwasm_register_error(as, l, E_SECTION_END);
 		return;
 	}
 
@@ -192,7 +207,7 @@
 	
 	if (as -> output_format != OUTPUT_OBJ)
 	{
-		lwasm_register_error(as, l, "EXPORT only supported for object target");
+		lwasm_register_error2(as, l, E_OBJTARGET_ONLY, "(%s)", "EXPORT");
 		return;
 	}
 
@@ -223,7 +238,7 @@
 	}
 	if (!sym)
 	{
-		lwasm_register_error(as, l, "No symbol for EXPORT");
+		lwasm_register_error2(as, l, E_SYMBOL_MISSING, "for %s", "EXPORT");
 		return;
 	}
 	
@@ -254,7 +269,7 @@
 	
 	if (as -> output_format != OUTPUT_OBJ)
 	{
-		lwasm_register_error(as, l, "IMPORT only supported for object target");
+		lwasm_register_error2(as, l, E_OBJTARGET_ONLY, "(%s)", "IMPORT");
 		return;
 	}
 	
@@ -285,7 +300,7 @@
 	}
 	if (!sym)
 	{
-		lwasm_register_error(as, l, "No symbol for IMPORT");
+		lwasm_register_error2(as, l, E_SYMBOL_MISSING, "for %s", "IMPORT");
 		return;
 	}
 	
@@ -314,13 +329,13 @@
 	
 	if (as -> output_format != OUTPUT_OBJ)
 	{
-		lwasm_register_error(as, l, "EXTDEP only supported for object target");
+		lwasm_register_error2(as, l, E_OBJTARGET_ONLY, "(%s)", "EXTDEP");
 		return;
 	}
 	
 	if (!as -> csect)
 	{
-		lwasm_register_error(as, l, "EXTDEP must be within a section");
+		lwasm_register_error(as, l, E_SECTION_EXTDEP);
 		return;
 	}
 	
@@ -347,7 +362,7 @@
 	}
 	if (!sym)
 	{
-		lwasm_register_error(as, l, "No symbol for EXTDEP");
+		lwasm_register_error2(as, l, E_SYMBOL_MISSING, "for %s", "EXTDEP");
 		return;
 	}
 	
--- a/lwasm/struct.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/struct.c	Mon Aug 05 21:27:09 2019 -0600
@@ -34,13 +34,13 @@
 	
 	if (as -> instruct)
 	{
-		lwasm_register_error(as, l, "Attempt to define a structure inside a structure");
+		lwasm_register_error(as, l, E_STRUCT_RECURSE);
 		return;
 	}
 	
 	if (l -> sym == NULL)
 	{
-		lwasm_register_error(as, l, "Structure definition with no effect - no symbol");
+		lwasm_register_error(as, l, E_STRUCT_NOSYMBOL);
 		return;
 	}
 	
@@ -52,7 +52,7 @@
 	
 	if (s)
 	{
-		lwasm_register_error(as, l, "Duplicate structure definition");
+		lwasm_register_error(as, l, E_STRUCT_DUPE);
 		return;
 	}
 	
@@ -138,7 +138,7 @@
 		
 	if (as -> instruct == 0)
 	{
-		lwasm_register_warning(as, l, "endstruct without struct");
+		lwasm_register_error(as, l, W_ENDSTRUCT_WITHOUT);
 		skip_operand(p);
 		return;
 	}
@@ -206,7 +206,7 @@
 	
 	if (!(l -> sym))
 	{
-		lwasm_register_error(as, l, "Cannot declare a structure without a symbol name.");
+		lwasm_register_error(as, l, E_STRUCT_NONAME);
 		return -1;
 	}
 
--- a/lwasm/symbol.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwasm/symbol.c	Mon Aug 05 21:27:09 2019 -0600
@@ -90,18 +90,18 @@
 	{
 		if (!sym || !*sym)
 		{
-			lwasm_register_error(as, cl, "Bad symbol (%s)", sym);
+			lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", sym);
 			return NULL;
 		}
-		if (*sym < 0x80 && (!strchr(SSYMCHARS, *sym) && !strchr(sym + 1, '$') && !strchr(sym + 1, '@') && !strchr(sym + 1, '?')))
+		if (*(unsigned char *)sym < 0x80 && (!strchr(SSYMCHARS, *sym) && !strchr(sym + 1, '$') && !strchr(sym + 1, '@') && !strchr(sym + 1, '?')))
 		{
-			lwasm_register_error(as, cl, "Bad symbol (%s)", sym);
+			lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", sym);
 			return NULL;
 		}
 
 		if ((*sym == '$' || *sym == '@') && (sym[1] >= '0' && sym[1] <= '9'))
 		{
-			lwasm_register_error(as, cl, "Bad symbol (%s)", sym);
+			lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", sym);
 			return NULL;
 		}
 	}
@@ -114,9 +114,9 @@
 			islocal = 1;
 		
 		// bad symbol
-		if (!(flags & symbol_flag_nocheck) && *cp < 0x80 && !strchr(SYMCHARS, *cp))
+		if (!(flags & symbol_flag_nocheck) && *(unsigned char *)cp < 0x80 && !strchr(SYMCHARS, *cp))
 		{
-			lwasm_register_error(as, cl, "Bad symbol (%s)", sym);
+			lwasm_register_error2(as, cl, E_SYMBOL_BAD, "(%s)", sym);
 			return NULL;
 		}
 	}
@@ -163,7 +163,7 @@
 	if (se && version == -1)
 	{
 		// multiply defined symbol
-		lwasm_register_error(as, cl, "Multiply defined symbol (%s)", sym);
+		lwasm_register_error2(as, cl, E_SYMBOL_DUPE, "(%s)", sym);
 		return NULL;
 	}
 
@@ -252,6 +252,8 @@
 	int local = 0;
 	struct symtabe *s;
 	int cdir;
+
+	debug_message(as, 100, "Look up symbol %s", sym);
 	
 	// check if this is a local symbol
 	if (strchr(sym, '@') || strchr(sym, '?'))
@@ -283,13 +285,17 @@
 		}
 		
 		if (!cdir)
+		{
+			debug_message(as, 100, "Found symbol %s: %s, %s", sym, s -> symbol, lw_expr_print(s -> value));
 			return s;
+		}
 		
 		if (cdir < 0)
 			s = s -> left;
 		else
 			s = s -> right;
 	}
+	debug_message(as, 100, "Symbol not found %s", sym);
 	return NULL;
 }
 
@@ -341,6 +347,10 @@
 	{	
 		if (s -> flags & symbol_flag_nolist)
 			continue;
+
+		if ((as -> flags & FLAG_SYMBOLS_NOLOCALS) && (s -> context >= 0))
+			continue;
+
 		lwasm_reduce_expr(as, s -> value);
 		fputc('[', of);
 		if (s -> flags & symbol_flag_set)
@@ -400,3 +410,77 @@
 	fprintf(of, "\nSymbol Table:\n");
 	list_symbols_aux(as, of, as -> symtab.head);
 }
+
+void map_symbols(asmstate_t *as, FILE *of, struct symtabe *se)
+{
+	struct symtabe *s;
+	lw_expr_t te;
+	struct listinfo li;
+
+	li.as = as;
+
+	if (!se)
+		return;
+
+	map_symbols(as, of, se -> left);
+
+	for (s = se; s; s = s -> nextver)
+	{
+		if (s -> flags & symbol_flag_nolist)
+			continue;
+		lwasm_reduce_expr(as, s -> value);
+
+		te = lw_expr_copy(s -> value);
+		li.complex = 0;
+		li.sect = NULL;
+		lw_expr_testterms(te, list_symbols_test, &li);
+		if (li.sect)
+		{
+			as -> exportcheck = 1;
+			as -> csect = li.sect;
+			lwasm_reduce_expr(as, te);
+			as -> exportcheck = 0;
+		}
+
+		if (lw_expr_istype(te, lw_expr_type_int))
+		{
+			fprintf(of, "Symbol: %s", s -> symbol);
+			if (s -> context != -1)
+				fprintf(of, "_%04X", lw_expr_intval(te));
+			fprintf(of, " (%s) = %04X\n", as -> output_file, lw_expr_intval(te));
+
+		}
+		lw_expr_destroy(te);
+	}
+
+	map_symbols(as, of, se -> right);
+}
+
+void do_map(asmstate_t *as)
+{
+	FILE *of = NULL;
+
+	if (!(as -> flags & FLAG_MAP))
+		return;
+
+	if (as -> map_file)
+	{
+		if (strcmp(as -> map_file, "-") == 0)
+		{
+			of = stdout;
+		}
+		else
+			of = fopen(as -> map_file, "w");
+	}
+	else
+		of = stdout;
+	if (!of)
+	{
+		fprintf(stderr, "Cannot open map file '%s' for output\n", as -> map_file);
+		return;
+	}
+
+	map_symbols(as, of, as -> symtab.head);
+
+	fclose(of);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwasm/symdump.c	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,146 @@
+/*
+symdump.c
+
+Copyright © 2019 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 of the License, or (at your option) any later
+version.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <lw_alloc.h>
+#include <lw_expr.h>
+#include <lw_string.h>
+
+#include "lwasm.h"
+
+struct listinfo
+{
+	sectiontab_t *sect;
+	asmstate_t *as;
+	int complex;
+};
+
+int dump_symbols_test(lw_expr_t e, void *p)
+{
+	struct listinfo *li = p;
+	
+	if (li -> complex)
+		return 0;
+	
+	if (lw_expr_istype(e, lw_expr_type_special))
+	{
+		if (lw_expr_specint(e) == lwasm_expr_secbase)
+		{
+			if (li -> sect)
+			{
+				li -> complex = 1;
+			}
+			else
+			{
+				li -> sect = lw_expr_specptr(e);
+			}
+		}
+	}
+	return 0;
+}
+
+void dump_symbols_aux(asmstate_t *as, FILE *of, struct symtabe *se)
+{
+	struct symtabe *s;
+	lw_expr_t te;
+	struct listinfo li;
+
+	li.as = as;
+	
+	if (!se)
+		return;
+	
+	dump_symbols_aux(as, of, se -> left);
+	
+	for (s = se; s; s = s -> nextver)
+	{	
+		if (s -> flags & symbol_flag_nolist)
+			continue;
+
+		if (s -> context >= 0)
+			continue;
+
+		lwasm_reduce_expr(as, s -> value);
+
+		fprintf(of, "%s ", s -> symbol);
+		if (s -> flags & symbol_flag_set)
+			fputs("SET", of);
+		else
+			fputs("EQU", of);
+		te = lw_expr_copy(s -> value);
+		li.complex = 0;
+		li.sect = NULL;
+		lw_expr_testterms(te, dump_symbols_test, &li);
+		if (li.sect)
+		{
+			as -> exportcheck = 1;
+			as -> csect = li.sect;
+			lwasm_reduce_expr(as, te);
+			as -> exportcheck = 0;
+		}
+		
+		if (lw_expr_istype(te, lw_expr_type_int))
+		{
+			fprintf(of, " $%04X\n", lw_expr_intval(te));
+		}
+		else
+		{
+			fprintf(of, " 0 ; <<incomplete>>\n");
+		}
+		lw_expr_destroy(te);
+	}
+	
+	dump_symbols_aux(as, of, se -> right);
+}
+
+void do_symdump(asmstate_t *as)
+{
+	FILE *of;
+	
+	if (!(as -> flags & FLAG_SYMDUMP))
+	{
+		return;
+	}
+	else
+	{		
+		if (as -> symbol_dump_file)
+		{
+			if (strcmp(as -> symbol_dump_file, "-") == 0)
+			{
+				of = stdout;
+			}
+			else
+				of = fopen(as -> symbol_dump_file, "w");
+		}
+		else
+			of = stdout;
+
+		if (!of)
+		{
+			fprintf(stderr, "Cannot open list file; list not generated\n");
+			return;
+		}
+	}
+	dump_symbols_aux(as, of, as -> symtab.head);
+}
--- a/lwlib/lw_alloc.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_alloc.c	Mon Aug 05 21:27:09 2019 -0600
@@ -20,8 +20,6 @@
 */
 
 #include <stdlib.h>
-
-#define ___lw_alloc_c_seen___
 #include "lw_alloc.h"
 
 void *lw_alloc(int size)
--- a/lwlib/lw_alloc.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_alloc.h	Mon Aug 05 21:27:09 2019 -0600
@@ -22,21 +22,8 @@
 #ifndef ___lw_alloc_h_seen___
 #define ___lw_alloc_h_seen___
 
-
-#ifdef ___lw_alloc_c_seen___
-
-#define ___E
-
-#else /* def ___lw_alloc_c_seen___ */
-
-#define ___E extern
-
-#endif /* def ___lw_alloc_c_seen___ */
-
-___E void lw_free(void *P);
-___E void *lw_alloc(int S);
-___E void *lw_realloc(void *P, int S);
-
-#undef ___E
+void lw_free(void *P);
+void *lw_alloc(int S);
+void *lw_realloc(void *P, int S);
 
 #endif /* ___lw_alloc_h_seen___ */
--- a/lwlib/lw_cmdline.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_cmdline.c	Mon Aug 05 21:27:09 2019 -0600
@@ -19,14 +19,13 @@
 this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 
 #include "lw_alloc.h"
-
-#define ___lw_cmdline_c_seen___
 #include "lw_cmdline.h"
 
 #define DOCCOL 30
@@ -382,7 +381,7 @@
 	int nextarg;
 	char *tstr;
 	int cch;
-	
+		
 	/* first, permute the argv array so that all option arguments are at the start */
 	for (i = 1, firstarg = 1; i < argc; i++)
 	{
@@ -498,7 +497,7 @@
 				fprintf(stderr, "Unknown option '%c'. See %s --usage.\n", argv[i][cch - 1], argv[0]);
 			else
 				fprintf(stderr, "Unknown option '%s'. See %s --usage.\n", argv[i - 1], argv[0]);
-			exit(1);
+			return EINVAL;
 		}
 		if (parser -> options[j].arg)
 		{
@@ -518,7 +517,7 @@
 			if (!tstr && (parser -> options[j].flags & lw_cmdline_opt_optional) == 0)
 			{
 				fprintf(stderr, "Option %s requires argument.\n", parser -> options[j].name);
-				continue;
+				return EINVAL;
 			}
 		}
 		r = (*(parser -> parser))(parser -> options[j].key, tstr, input);
--- a/lwlib/lw_cmdline.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_cmdline.h	Mon Aug 05 21:27:09 2019 -0600
@@ -70,13 +70,6 @@
 	char *program_version;
 };
 
-#ifdef ___lw_cmdline_c_seen___
-
-#else /* def ___lw_cmdline_c_seen___ */
-
-extern int lw_cmdline_parse(struct lw_cmdline_parser *parser, int argc, char **argv, unsigned flags, int *arg_index, void *input);
-
-
-#endif /* def ___lw_cmdline_c_seen___ */
+int lw_cmdline_parse(struct lw_cmdline_parser *parser, int argc, char **argv, unsigned flags, int *arg_index, void *input);
 
 #endif /* ___lw_cmdline_h_seen___ */
--- a/lwlib/lw_error.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_error.c	Mon Aug 05 21:27:09 2019 -0600
@@ -19,7 +19,6 @@
 this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
-#define ___lw_error_c_seen___
 #include "lw_error.h"
 
 #include <stdio.h>
--- a/lwlib/lw_error.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_error.h	Mon Aug 05 21:27:09 2019 -0600
@@ -22,13 +22,7 @@
 #ifndef ___lw_error_h_seen___
 #define ___lw_error_h_seen___
 
-
-#ifdef ___lw_error_c_seen___
-
-#else /* def ___lw_error_c_seen___ */
-
-extern void lw_error(const char *fmt, ...);
-extern void lw_error_setfunc(void (*f)(const char *fmt, ...));
-#endif /* def ___lw_error_c_seen___ */
+void lw_error(const char *fmt, ...);
+void lw_error_setfunc(void (*f)(const char *fmt, ...));
 
 #endif /* ___lw_error_h_seen___ */
--- a/lwlib/lw_expr.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_expr.c	Mon Aug 05 21:27:09 2019 -0600
@@ -24,7 +24,6 @@
 #include <string.h>
 #include <ctype.h>
 
-#define ___lw_expr_c_seen___
 #include "lw_alloc.h"
 #include "lw_expr.h"
 #include "lw_error.h"
@@ -37,9 +36,17 @@
 /* Q&D to break out of infinite recursion */
 static int level = 0;
 static int bailing = 0;
+static int parse_compact = 0;
 
 static void (*divzero)(void *priv) = NULL;
 
+static int expr_width = 0;
+
+void lw_expr_setwidth(int w)
+{
+	expr_width = w;
+}
+
 void lw_expr_setdivzero(void (*fn)(void *priv))
 {
 	divzero = fn;
@@ -73,7 +80,11 @@
 int lw_expr_whichop(lw_expr_t e)
 {
 	if (e -> type == lw_expr_type_oper)
+	{
+		if (e -> value == lw_expr_oper_com8)
+			return lw_expr_oper_com;
 		return e -> value;
+	}
 	return -1;
 }
 
@@ -202,7 +213,7 @@
 	case lw_expr_type_oper:
 		t = va_arg(args, int);
 		te1 = va_arg(args, lw_expr_t);
-		if (t != lw_expr_oper_com && t != lw_expr_oper_neg)
+		if (t != lw_expr_oper_com && t != lw_expr_oper_neg && t != lw_expr_oper_com8)
 			te2 = va_arg(args, lw_expr_t);
 		else
 			te2 = NULL;
@@ -321,6 +332,10 @@
 		case lw_expr_oper_com:
 			strcat(buf, "COM ");
 			break;
+		
+		case lw_expr_oper_com8:
+			strcat(buf, "COM8 ");
+			break;
 			
 		default:
 			strcat(buf, "OPER ");
@@ -577,7 +592,7 @@
 		te = evaluate_special(E -> value, E -> value2, priv);
 		if (lw_expr_contains(te, E))
 			lw_expr_destroy(te);
-		if (te)
+		else if (te)
 		{
 			for (o = E -> operands; o; o = o -> next)
 				lw_expr_destroy(o -> p);
@@ -606,6 +621,8 @@
 		lw_expr_t te;
 		
 		te = evaluate_var(E -> value2, priv);
+		if (!te)
+			return;
 		if (lw_expr_contains(te, E))
 			lw_expr_destroy(te);
 		else if (te)
@@ -715,6 +732,10 @@
 			tr = ~(E -> operands -> p -> value);
 			break;
 		
+		case lw_expr_oper_com8:
+			tr = ~(E -> operands -> p -> value) & 0xff;
+			break;
+		
 		case lw_expr_oper_plus:
 			tr = E -> operands -> p -> value;
 			for (o = E -> operands -> next; o; o = o -> next)
@@ -927,11 +948,18 @@
 					}
 					lw_expr_destroy(o -> p);
 					o -> p = e1;
-					for (o = o2 -> p -> operands; o; o = o -> next)
+					if (o2 -> p -> type == lw_expr_type_oper)
 					{
-						if (o -> p -> type == lw_expr_type_int)
-							continue;
-						lw_expr_add_operand(e1, o -> p);
+						for (o = o2 -> p -> operands; o; o = o -> next)
+						{
+							if (o -> p -> type == lw_expr_type_int)
+								continue;
+							lw_expr_add_operand(e1, o -> p);
+						}
+					}
+					else
+					{
+						lw_expr_add_operand(e1, o2 -> p);
 					}
 					lw_expr_destroy(o2 -> p);
 					o2 -> p = lw_expr_build(lw_expr_type_int, 0);
@@ -1123,7 +1151,7 @@
 following conditions:
 
 1. a NUL character
-2. a whitespace character
+2. a whitespace character (if parse mode is "COMPACT")
 3. a )
 4. a ,
 5. any character that is not recognized as a term
@@ -1137,19 +1165,29 @@
 
 lw_expr_t lw_expr_parse_expr(char **p, void *priv, int prec);
 
+static void lw_expr_parse_next_tok(char **p)
+{
+	if (parse_compact)
+		return;
+	for (; **p && isspace(**p); (*p)++)
+		/* do nothing */ ;
+}
+
 lw_expr_t lw_expr_parse_term(char **p, void *priv)
 {
 	lw_expr_t term, term2;
 	
 eval_next:
+	lw_expr_parse_next_tok(p);
+
 	if (!**p || isspace(**p) || **p == ')' || **p == ']')
 		return NULL;
-
 	// parentheses
 	if (**p == '(')
 	{
 		(*p)++;
 		term = lw_expr_parse_expr(p, priv, 0);
+		lw_expr_parse_next_tok(p);
 		if (**p != ')')
 		{
 			lw_expr_destroy(term);
@@ -1187,7 +1225,10 @@
 		if (!term)
 			return NULL;
 		
-		term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term);
+		if (expr_width == 8)
+			term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com8, term);
+		else
+			term2 = lw_expr_build(lw_expr_type_oper, lw_expr_oper_com, term);
 		lw_expr_destroy(term);
 		return term2;
 	}
@@ -1226,7 +1267,8 @@
 	int opern, i;
 	lw_expr_t term1, term2, term3;
 	
-	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']')
+	lw_expr_parse_next_tok(p);
+	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
 		return NULL;
 
 	term1 = lw_expr_parse_term(p, priv);
@@ -1234,7 +1276,8 @@
 		return NULL;
 
 eval_next:
-	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']')
+	lw_expr_parse_next_tok(p);
+	if (!**p || isspace(**p) || **p == ')' || **p == ',' || **p == ']' || **p == ';')
 		return term1;
 	
 	// expecting an operator here
@@ -1291,9 +1334,17 @@
 
 lw_expr_t lw_expr_parse(char **p, void *priv)
 {
+	parse_compact = 0;
 	return lw_expr_parse_expr(p, priv, 0);
 }
 
+lw_expr_t lw_expr_parse_compact(char **p, void *priv)
+{
+	parse_compact = 1;
+	return lw_expr_parse_expr(p, priv, 0);
+}
+	
+
 int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv)
 {
 	struct lw_expr_opers *o;
--- a/lwlib/lw_expr.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_expr.h	Mon Aug 05 21:27:09 2019 -0600
@@ -24,6 +24,10 @@
 
 #include <stdio.h>
 
+#ifdef _MSC_VER
+#include "lw_win.h"	// windows build
+#endif
+
 enum
 {
 	lw_expr_type_oper,			// operator term
@@ -47,11 +51,10 @@
 	lw_expr_oper_or,			// boolean or
 	lw_expr_oper_neg,			// unary negation, 2's complement
 	lw_expr_oper_com,			// unary 1's complement
+	lw_expr_oper_com8,			// 8 bit complement
 	lw_expr_oper_none = 0
 };
 
-#ifdef ___lw_expr_c_seen___
-
 typedef struct lw_expr_priv * lw_expr_t;
 
 struct lw_expr_opers
@@ -73,47 +76,38 @@
 typedef lw_expr_t lw_expr_fn3_t(char **p, void *priv);
 typedef int lw_expr_testfn_t(lw_expr_t e, void *priv);
 
-#else /* def ___lw_expr_c_seen___ */
-
-typedef void * lw_expr_t;
+lw_expr_t lwexpr_create(void);
+void lw_expr_destroy(lw_expr_t E);
+lw_expr_t lw_expr_copy(lw_expr_t E);
+void lw_expr_add_operand(lw_expr_t E, lw_expr_t O);
+lw_expr_t lw_expr_build(int exprtype, ...);
+char *lw_expr_print(lw_expr_t E);
+int lw_expr_compare(lw_expr_t E1, lw_expr_t E2);
+void lw_expr_simplify(lw_expr_t E, void *priv);
 
-extern lw_expr_t lwexpr_create(void);
-extern void lw_expr_destroy(lw_expr_t E);
-extern lw_expr_t lw_expr_copy(lw_expr_t E);
-extern void lw_expr_add_operand(lw_expr_t E, lw_expr_t O);
-extern lw_expr_t lw_expr_build(int exprtype, ...);
-extern char *lw_expr_print(lw_expr_t E);
-extern int lw_expr_compare(lw_expr_t E1, lw_expr_t E2);
-extern void lw_expr_simplify(lw_expr_t E, void *priv);
-
-typedef lw_expr_t lw_expr_fn_t(int t, void *ptr, void *priv);
-typedef lw_expr_t lw_expr_fn2_t(char *var, void *priv);
-typedef lw_expr_t lw_expr_fn3_t(char **p, void *priv);
+void lw_expr_set_special_handler(lw_expr_fn_t *fn);
+void lw_expr_set_var_handler(lw_expr_fn2_t *fn);
+void lw_expr_set_term_parser(lw_expr_fn3_t *fn);
 
-extern void lw_expr_set_special_handler(lw_expr_fn_t *fn);
-extern void lw_expr_set_var_handler(lw_expr_fn2_t *fn);
-extern void lw_expr_set_term_parser(lw_expr_fn3_t *fn);
+lw_expr_t lw_expr_parse(char **p, void *priv);
+lw_expr_t lw_expr_parse_compact(char **p, void *priv);
+int lw_expr_istype(lw_expr_t e, int t);
+int lw_expr_intval(lw_expr_t e);
+int lw_expr_specint(lw_expr_t e);
+void *lw_expr_specptr(lw_expr_t e);
+int lw_expr_whichop(lw_expr_t e);
 
-extern lw_expr_t lw_expr_parse(char **p, void *priv);
-extern int lw_expr_istype(lw_expr_t e, int t);
-extern int lw_expr_intval(lw_expr_t e);
-extern int lw_expr_specint(lw_expr_t e);
-extern void *lw_expr_specptr(lw_expr_t e);
-extern int lw_expr_whichop(lw_expr_t e);
+int lw_expr_type(lw_expr_t e);
 
-extern int lw_expr_type(lw_expr_t e);
+int lw_expr_operandcount(lw_expr_t e);
 
-typedef int lw_expr_testfn_t(lw_expr_t e, void *priv);
-
-extern int lw_expr_operandcount(lw_expr_t e);
+void lw_expr_setwidth(int w);
 
 // run a function on all terms in an expression; if the function
 // returns non-zero for any term, return non-zero, else return
 // zero
-extern int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv);
+int lw_expr_testterms(lw_expr_t e, lw_expr_testfn_t *fn, void *priv);
 
-extern void lw_expr_setdivzero(void (*fn)(void *priv));
-
-#endif /* def ___lw_expr_c_seen___ */
+void lw_expr_setdivzero(void (*fn)(void *priv));
 
 #endif /* ___lw_expr_h_seen___ */
--- a/lwlib/lw_free.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_free.c	Mon Aug 05 21:27:09 2019 -0600
@@ -21,7 +21,6 @@
 
 #include <stdlib.h>
 
-#define ___lw_alloc_c_seen___
 #include "lw_alloc.h"
 
 void lw_free(void *P)
--- a/lwlib/lw_realloc.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_realloc.c	Mon Aug 05 21:27:09 2019 -0600
@@ -21,7 +21,6 @@
 
 #include <stdlib.h>
 
-#define ___lw_alloc_c_seen___
 #include "lw_alloc.h"
 
 void *lw_realloc(void *P, int S)
--- a/lwlib/lw_stack.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_stack.h	Mon Aug 05 21:27:09 2019 -0600
@@ -42,11 +42,11 @@
 #else /* def ___lw_stack_c_seen___ */
 
 typedef void * lw_stack_t;
-extern lw_stack_t lw_stack_create(void (*freefn)(void *d));
-extern void lw_stack_destroy(lw_stack_t S);
-extern void *lw_stack_top(lw_stack_t S);
-extern void *lw_stack_pop(lw_stack_t S);
-extern void lw_stack_push(lw_stack_t S, void *item);
+lw_stack_t lw_stack_create(void (*freefn)(void *d));
+void lw_stack_destroy(lw_stack_t S);
+void *lw_stack_top(lw_stack_t S);
+void *lw_stack_pop(lw_stack_t S);
+void lw_stack_push(lw_stack_t S, void *item);
 
 #endif /* def ___lw_stack_c_seen___ */
 
--- a/lwlib/lw_string.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_string.c	Mon Aug 05 21:27:09 2019 -0600
@@ -22,7 +22,6 @@
 #include <string.h>
 #include <stdlib.h>
 
-#define ___lw_string_c_seen___
 #include "lw_alloc.h"
 #include "lw_string.h"
 
--- a/lwlib/lw_string.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_string.h	Mon Aug 05 21:27:09 2019 -0600
@@ -22,15 +22,8 @@
 #ifndef ___lw_string_h_seen___
 #define ___lw_string_h_seen___
 
-
-#ifdef ___lw_string_c_seen___
-
-#else /* def ___lw_string_c_seen___ */
-
-extern char *lw_strdup(const char *s);
-extern char *lw_strndup(const char *s, int len);
-extern char *lw_token(const char *s, int sep, const char **ap);
-
-#endif /* def ___lw_string_c_seen___ */
+char *lw_strdup(const char *s);
+char *lw_strndup(const char *s, int len);
+char *lw_token(const char *s, int sep, const char **ap);
 
 #endif /* ___lw_string_h_seen___ */
--- a/lwlib/lw_stringlist.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlib/lw_stringlist.h	Mon Aug 05 21:27:09 2019 -0600
@@ -36,14 +36,14 @@
 #else /* def ___lw_stringlist_c_seen___ */
 
 typedef void * lw_stringlist_t;
-extern lw_stringlist_t lw_stringlist_create(void);
-extern void lw_stringlist_destroy(lw_stringlist_t S);
-extern void lw_stringlist_addstring(lw_stringlist_t S, char *str);
-extern void lw_stringlist_reset(lw_stringlist_t S);
-extern char *lw_stringlist_current(lw_stringlist_t S);
-extern char *lw_stringlist_next(lw_stringlist_t S);
-extern int lw_stringlist_nstrings(lw_stringlist_t S);
-extern lw_stringlist_t lw_stringlist_copy(lw_stringlist_t S);
+lw_stringlist_t lw_stringlist_create(void);
+void lw_stringlist_destroy(lw_stringlist_t S);
+void lw_stringlist_addstring(lw_stringlist_t S, char *str);
+void lw_stringlist_reset(lw_stringlist_t S);
+char *lw_stringlist_current(lw_stringlist_t S);
+char *lw_stringlist_next(lw_stringlist_t S);
+int lw_stringlist_nstrings(lw_stringlist_t S);
+lw_stringlist_t lw_stringlist_copy(lw_stringlist_t S);
 
 #endif /* def ___lw_stringlist_c_seen___ */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lw_win.c	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,49 @@
+/*
+lw_win.c
+
+Copyright © 2015 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 of the License, or (at your option) any later
+version.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "lw_win.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+int c99_vsnprintf(char* str, size_t size, const char* format, va_list ap)
+{
+	int count = -1;
+
+	if (size != 0)
+		count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
+	if (count == -1)
+		count = _vscprintf(format, ap);
+
+	return count;
+}
+
+int c99_snprintf(char* str, size_t size, const char* format, ...)
+{
+	int count;
+	va_list ap;
+
+	va_start(ap, format);
+	count = c99_vsnprintf(str, size, format, ap);
+	va_end(ap);
+
+	return count;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lwlib/lw_win.h	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,36 @@
+/*
+lw_win.h
+
+Copyright © 2015 William Astle
+
+This file is part of LWTOOLS.
+
+LWTOOLS 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 of the License, or (at your option) any later
+version.
+
+This program 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
+this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ___lw_win_h_seen___
+#define ___lw_win_h_seen___
+
+#include "lw_string.h"
+#include <string.h>
+
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+#define unlink _unlink
+
+int c99_snprintf(char* str, size_t size, const char* format, ...);
+
+#define snprintf c99_snprintf
+
+#endif /* ___lw_win_h_seen___ */
--- a/lwlink/link.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/link.c	Mon Aug 05 21:27:09 2019 -0600
@@ -31,6 +31,10 @@
 #include "expr.h"
 #include "lwlink.h"
 
+#ifdef _MSC_VER
+#include <lw_win.h>	// windows build
+#endif
+
 void check_os9(void);
 
 struct section_list *sectlist = NULL;
@@ -44,13 +48,19 @@
 
 sectopt_t *section_opts = NULL;
 
-void check_section_name(char *name, int *base, fileinfo_t *fn)
+void check_section_name(char *name, int *base, fileinfo_t *fn, int down)
 {
 	int sn;
+	sectopt_t *so;
+	
 //	fprintf(stderr, "Considering sections in %s (%d) for %s\n", fn -> filename, fn -> forced, name);
 	if (fn -> forced == 0)
 		return;
 
+	for (so = section_opts; so; so = so -> next)
+		if (!strcmp(so -> name, name))
+			break;
+
 	for (sn = 0; sn < fn -> nsections; sn++)
 	{
 //		fprintf(stderr, "    Considering section %s\n", fn -> sections[sn].name);
@@ -62,22 +72,39 @@
 //			fprintf(stderr, "    Found\n");
 			sectlist = lw_realloc(sectlist, sizeof(struct section_list) * (nsects + 1));
 			sectlist[nsects].ptr = &(fn -> sections[sn]);
-					
+			
+				
 			fn -> sections[sn].processed = 1;
-			fn -> sections[sn].loadaddress = *base;
-			*base += fn -> sections[sn].codesize;
+			if (down)
+			{
+				*base -= fn -> sections[sn].codesize;
+				fn -> sections[sn].loadaddress = *base;
+			}
+			else
+			{
+				fn -> sections[sn].loadaddress = *base;
+				*base += fn -> sections[sn].codesize;
+			}
+			if (down && so && so -> aftersize)
+			{
+				sectlist[nsects].ptr -> afterbytes = so -> afterbytes;
+				sectlist[nsects].ptr -> aftersize = so -> aftersize;
+				sectlist[nsects].ptr -> loadaddress -= so -> aftersize;
+				*base -= so -> aftersize;
+				so -> aftersize = 0;
+			}
 			nsects++;
 //			fprintf(stderr, "Adding section %s (%s)\n",fn -> sections[sn].name, fn -> filename);
 		}
 	}
 	for (sn = 0; sn < fn -> nsubs; sn++)
 	{
-		check_section_name(name, base, fn -> subs[sn]);
+		check_section_name(name, base, fn -> subs[sn], down);
 	}
 }
 
-void add_matching_sections(char *name, int yesflags, int noflags, int *base);
-void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn)
+void add_matching_sections(char *name, int yesflags, int noflags, int *base, int down);
+void check_section_flags(int yesflags, int noflags, int *base, fileinfo_t *fn, int down)
 {
 	int sn;
 	sectopt_t *so;
@@ -104,7 +131,7 @@
 
 		// we have a match - now collect *all* sections of the same name!
 //		fprintf(stderr, "    Found\n");
-		add_matching_sections((char *)(fn -> sections[sn].name), 0, 0, base);
+		add_matching_sections((char *)(fn -> sections[sn].name), 0, 0, base, down);
 
 		/* handle "after padding" */
 		for (so = section_opts; so; so = so -> next)
@@ -116,7 +143,15 @@
 			{
 				sectlist[nsects - 1].ptr -> afterbytes = so -> afterbytes;
 				sectlist[nsects - 1].ptr -> aftersize = so -> aftersize;
-				*base += so -> aftersize;
+				if (down)
+				{
+					sectlist[nsects - 1].ptr -> loadaddress -= so -> aftersize;
+					*base -= so -> aftersize;
+				}
+				else
+				{
+					*base += so -> aftersize;
+				}
 			}
 		}
 		
@@ -124,13 +159,13 @@
 	}
 	for (sn = 0; sn < fn -> nsubs; sn++)
 	{
-		check_section_flags(yesflags, noflags, base, fn -> subs[sn]);
+		check_section_flags(yesflags, noflags, base, fn -> subs[sn], down);
 	}
 }
 
 
 
-void add_matching_sections(char *name, int yesflags, int noflags, int *base)
+void add_matching_sections(char *name, int yesflags, int noflags, int *base, int down)
 {
 	int fn;
 	if (name)
@@ -140,7 +175,7 @@
 		// and resolve base addresses and add to the list
 		for (fn = 0; fn < ninputfiles; fn++)
 		{
-			check_section_name(name, base, inputfiles[fn]);
+			check_section_name(name, base, inputfiles[fn], down);
 		}
 	}
 	else
@@ -151,7 +186,7 @@
 		// and resolve base addresses and add to the list
 		for (fn = 0; fn < ninputfiles; fn++)
 		{
-			check_section_flags(yesflags, noflags, base, inputfiles[fn]);
+			check_section_flags(yesflags, noflags, base, inputfiles[fn], down);
 		}
 	}
 }
@@ -161,15 +196,19 @@
 void resolve_sections(void)
 {
 	int laddr = 0;
+	int growdown = 0;
 	int ln, sn, fn;
 	sectopt_t *so;
 	
 	for (ln = 0; ln < linkscript.nlines; ln++)
 	{
 		if (linkscript.lines[ln].loadat >= 0)
+		{
 			laddr = linkscript.lines[ln].loadat;
+			growdown = linkscript.lines[ln].growsdown;
+		}
 		//fprintf(stderr, "Adding section %s\n", linkscript.lines[ln].sectname);
-		add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr);
+		add_matching_sections(linkscript.lines[ln].sectname, linkscript.lines[ln].yesflags, linkscript.lines[ln].noflags, &laddr, growdown);
 		
 		if (linkscript.lines[ln].sectname)
 		{
@@ -184,7 +223,15 @@
 				{
 					sectlist[nsects - 1].ptr -> afterbytes = so -> afterbytes;
 					sectlist[nsects - 1].ptr -> aftersize = so -> aftersize;
-					laddr += so -> aftersize;
+					if (growdown)
+					{
+						sectlist[nsects-1].ptr -> loadaddress -= so -> aftersize;
+						laddr -= so -> aftersize;
+					}
+					else
+					{
+						laddr += so -> aftersize;
+					}
 				}
 			}
 		}
@@ -233,13 +280,22 @@
 										f = 1;
 										sectlist[nsects].forceaddr = 1;
 										laddr = linkscript.lines[ln].loadat;
+										growdown = linkscript.lines[ln].growsdown;
 									}
 									else
 									{
 										sectlist[nsects].forceaddr = 0;
 									}
-									inputfiles[fn] -> sections[sn].loadaddress = laddr;
-									laddr += inputfiles[fn] -> sections[sn].codesize;
+									if (growdown)
+									{
+										laddr -= inputfiles[fn] -> sections[sn].codesize;
+										inputfiles[fn] -> sections[sn].loadaddress = laddr;
+									}
+									else
+									{
+										inputfiles[fn] -> sections[sn].loadaddress = laddr;
+										laddr += inputfiles[fn] -> sections[sn].codesize;
+									}
 									nsects++;
 								}
 							}
@@ -261,6 +317,8 @@
 	char sym[256];
 	int len;
 	symlist_t *se;
+	int lowaddr;
+	
 	for (sn = 0; sn < nsects; sn++)
 	{
 		if (!lastsect || strcmp(lastsect, (char *)(sectlist[sn].ptr -> name)))
@@ -275,20 +333,22 @@
 				se -> next = symlist;
 				symlist = se;
 			}
-			lastsect = (char *)(sectlist[sn].ptr -> name);
-			len = 0;
-			/* handle base symbol */
 			if (lastsect && linkscript.basesympat)
 			{
 				se = lw_alloc(sizeof(symlist_t));
-				se -> val = sectlist[sn].ptr -> loadaddress;
+				se -> val = lowaddr;
 				snprintf(sym, 255, linkscript.basesympat, lastsect);
 				se -> sym = lw_strdup(sym);
 				se -> next = symlist;
 				symlist = se;
 			}
+			lastsect = (char *)(sectlist[sn].ptr -> name);
+			len = 0;
+			lowaddr = sectlist[sn].ptr -> loadaddress;
 		}
 		len += sectlist[sn].ptr -> codesize;
+		if (sectlist[sn].ptr -> loadaddress < lowaddr)
+			lowaddr = sectlist[sn].ptr -> loadaddress;
 	}
 	if (lastsect && linkscript.lensympat)
 	{
@@ -300,7 +360,15 @@
 		se -> next = symlist;
 		symlist = se;
 	}
-
+	if (lastsect && linkscript.basesympat)
+	{
+		se = lw_alloc(sizeof(symlist_t));
+		se -> val = lowaddr;
+		snprintf(sym, 255, linkscript.basesympat, lastsect);
+		se -> sym = lw_strdup(sym);
+		se -> next = symlist;
+		symlist = se;
+	}
 }
 
 lw_expr_stack_t *find_external_sym_recurse(char *sym, fileinfo_t *fn)
@@ -646,7 +714,7 @@
 		if (inputfiles[fn] -> forced == 1)
 			continue;
 		
-		fprintf(stderr, "Warning: %s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn);
+		fprintf(stderr, "Warning: library -l%s (%d) does not resolve any symbols\n", inputfiles[fn] -> filename, fn);
 	}
 }
 void find_section_by_name_once_aux(char *name, fileinfo_t *fn, section_t **rval, int *found);
--- a/lwlink/lwlink.h	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/lwlink.h	Mon Aug 05 21:27:09 2019 -0600
@@ -30,6 +30,7 @@
 #define OUTPUT_RAW		1	// raw sequence of bytes
 #define OUTPUT_LWEX0	2	// LWOS LWEX binary version 0
 #define OUTPUT_OS9		3	// OS9 object code module
+#define OUTPUT_SREC		4	// motorola SREC format
 
 typedef struct symtab_s symtab_t;
 struct symtab_s
@@ -79,7 +80,7 @@
 {
 	char *filename;
 	unsigned char *filedata;
-	long filesize;
+	int filesize;
 	section_t *sections;
 	int nsections;
 	int islib;				// set to true if the file is a "-l" option
@@ -156,6 +157,7 @@
 	int loadat;					// address to load at (or -1)
 	int noflags;				// flags to NOT have
 	int yesflags;				// flags to HAVE
+	int growsdown;				// sections are placed descending in memory
 };
 
 typedef struct
--- a/lwlink/main.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/main.c	Mon Aug 05 21:27:09 2019 -0600
@@ -25,13 +25,20 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <string.h>
 
 #include <lw_cmdline.h>
 
+#include <version.h>
+
 #include "lwlink.h"
 
+#ifdef _MSC_VER
+#include <lw_win.h>	// windows build
+#else
+#include <unistd.h>
+#endif
+
 char *program_name;
 
 // command line option handling
@@ -81,6 +88,8 @@
 			outformat = OUTPUT_LWEX0;
 		else if (!strcasecmp(arg, "os9"))
 			outformat = OUTPUT_OS9;
+		else if (!strcasecmp(arg, "srec"))
+			outformat = OUTPUT_SREC;
 		else
 		{
 			fprintf(stderr, "Invalid output format: %s\n", arg);
@@ -130,7 +139,7 @@
 	{ "debug",		'd',	0,		0,
 				"Set debug mode"},
 	{ "format",		'f',	"TYPE",	0,
-				"Select output format: decb, raw, lwex, os9"},
+				"Select output format: decb, raw, lwex, os9, srec"},
 	{ "decb",		'b',	0,		0,
 				"Generate DECB .bin format output, equivalent of --format=decb"},
 	{ "raw",		'r',	0,		0,
@@ -177,7 +186,11 @@
 {
 	program_name = argv[0];
 
-	lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL);
+	if (lw_cmdline_parse(&cmdline_parser, argc, argv, 0, 0, NULL) != 0)
+	{
+		// bail if parsing failed
+		exit(1);
+	}
 	if (ninputfiles == 0)
 	{
 		fprintf(stderr, "No input files\n");
--- a/lwlink/output.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/output.c	Mon Aug 05 21:27:09 2019 -0600
@@ -37,6 +37,7 @@
 void do_output_decb(FILE *of);
 void do_output_raw(FILE *of);
 void do_output_lwex0(FILE *of);
+void do_output_srec(FILE *of);
 
 void do_output(void)
 {
@@ -68,6 +69,10 @@
 		do_output_os9(of);
 		break;
 		
+	case OUTPUT_SREC:
+		do_output_srec(of);
+		break;
+		
 	default:
 		fprintf(stderr, "Unknown output format doing output!\n");
 		exit(111);
@@ -161,6 +166,59 @@
 	}
 }
 
+void do_output_srec(FILE *of)
+{
+	const int SRECLEN = 16;
+
+	int sn;	
+	int remainingcodebytes;
+	
+	int codeaddr;
+	int i;
+	int recaddr = 0;
+	int recdlen = 0;
+	int recsum;
+	int reccnt = -1;
+	unsigned char* sectcode;
+	// no header yet; unnecessary
+
+	for (sn = 0; sn < nsects; sn++)				// check all sections
+	{
+		if (sectlist[sn].ptr -> flags & SECTION_BSS)	// ignore BSS sections
+			continue;
+		if (sectlist[sn].ptr -> codesize == 0)		// ignore empty sections
+			continue;
+
+		recaddr = sectlist[sn].ptr -> loadaddress;
+		remainingcodebytes = sectlist[sn].ptr -> codesize;
+		sectcode = sectlist[sn].ptr -> code;
+		
+		while (remainingcodebytes) 
+		{
+			recdlen = (SRECLEN>remainingcodebytes)?remainingcodebytes:SRECLEN;
+			recsum = recdlen + 3;
+			codeaddr = recaddr - sectlist[sn].ptr -> loadaddress;			
+			fprintf(of, "S1%02X%04X", recdlen + 3, recaddr & 0xffff);
+			for (i = 0; i < recdlen; i++)
+			{
+				fprintf(of, "%02X", sectcode[codeaddr+i]);
+				recsum += sectcode[codeaddr+i];
+			}
+			recsum += (recaddr >> 8) & 0xFF;
+			recsum += recaddr & 0xFF;
+			fprintf(of, "%02X\r\n", (unsigned char)(~recsum));
+			reccnt += 1;
+			remainingcodebytes -= recdlen;
+			recaddr += recdlen;
+		}
+	}
+	// S9 record as a footer to inform about start addr
+	recsum = 3;
+	recsum += (linkscript.execaddr >> 8) & 0xFF;
+	recsum += linkscript.execaddr & 0xFF;
+	fprintf(of,"S903%04X%02X\r\n",linkscript.execaddr,(unsigned char)(~recsum));
+}
+
 void do_output_lwex0(FILE *of)
 {
 	int nskips = 0;		// used to output blanks for BSS inline
@@ -338,7 +396,7 @@
 	
 	if (linkscript.edition >= 0)
 	{
-		buf[0] = linkscript.edition & 0x80;
+		buf[0] = linkscript.edition & 0xff;
 		writebytes(buf, 1, 1, of);
 		os9crc(crc, buf[0]);
 	}
--- a/lwlink/readfiles.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/readfiles.c	Mon Aug 05 21:27:09 2019 -0600
@@ -70,25 +70,37 @@
 		if (inputfiles[i] -> islib)
 		{
 			char *tf;
+			char *sfn;
 			int s;
 			int j;
 			
 			f = NULL;
 			
+			if (inputfiles[i] -> filename[0] == ':')
+			{
+				// : suppresses the libfoo.a behaviour
+				sfn = lw_strdup(inputfiles[i] -> filename + 1);
+			}
+			else
+			{
+				sfn = lw_alloc(strlen(inputfiles[i] -> filename) + 6);
+				sprintf(sfn, "lib%s.a", inputfiles[i] -> filename);
+			}
+			
 			for (j = 0; j < nlibdirs; j++)
 			{
 				if (libdirs[j][0] == '=')
 				{
 					// handle sysroot
-					s = strlen(libdirs[j]) + 7 + strlen(sysroot) + strlen(inputfiles[i] -> filename);
+					s = strlen(libdirs[j]) + 2 + strlen(sysroot) + strlen(sfn);
 					tf = lw_alloc(s + 1);
-					sprintf(tf, "%s/%s/lib%s.a", sysroot, libdirs[j] + 1, inputfiles[i] -> filename);
+					sprintf(tf, "%s/%s/%s", sysroot, libdirs[j] + 1, sfn);
 				}
 				else
 				{
-					s = strlen(libdirs[j]) + 7 + strlen(inputfiles[i] -> filename);
+					s = strlen(libdirs[j]) + 1 + strlen(sfn);
 					tf = lw_alloc(s + 1);
-					sprintf(tf, "%s/lib%s.a", libdirs[j], inputfiles[i] -> filename);
+					sprintf(tf, "%s/%s", libdirs[j], sfn);
 				}
 				f = fopen(tf, "rb");
 				if (!f)
@@ -99,6 +111,7 @@
 				free(tf);
 				break;
 			}
+			free(sfn);
 			if (!f)
 			{
 				fprintf(stderr, "Can't open library: -l%s\n", inputfiles[i] -> filename);
@@ -388,8 +401,8 @@
 */
 void read_lwar1v(fileinfo_t *fn)
 {
-	unsigned long cc = 6;
-	unsigned long flen;
+	int cc = 6;
+	int flen;
 	unsigned long l;
 	for (;;)
 	{
--- a/lwlink/script.c	Mon Aug 05 21:07:14 2019 -0600
+++ b/lwlink/script.c	Mon Aug 05 21:27:09 2019 -0600
@@ -58,6 +58,17 @@
 	"entry 2000\n"
 	;
 
+// the built-in SREC target linker script
+static char *srec_script =
+	"define basesympat s_%s\n"
+	"define lensympat l_%s\n"
+	"section init load 0400\n"
+	"section code\n"
+	"section *,!bss\n"
+	"section *,bss\n"
+	"entry __start\n"
+	;
+
 // the built-in RAW target linker script
 static char *raw_script = 
 	"define basesympat s_%s\n"
@@ -147,6 +158,10 @@
 			script = decb_script;
 			break;
 		
+		case OUTPUT_SREC:
+			script = srec_script;
+			break;
+		
 		case OUTPUT_LWEX0:
 			script = lwex0_script;
 			break;
@@ -214,8 +229,8 @@
 		for (ptr = line; *ptr && isspace(*ptr); ptr++)
 			/* do nothing */ ;
 		
-		// ignore blank lines
-		if (!*ptr)
+		// ignore blank lines and comments
+		if (!*ptr || *ptr == '#' || *ptr == ';')
 			continue;
 		
 		for (ptr = line; *ptr && !isspace(*ptr); ptr++)
@@ -380,6 +395,7 @@
 		}
 		else if (!strcmp(line, "section"))
 		{
+			int growsdown = 0;
 			// section
 			// parse out the section name and flags
 			for (ptr2 = ptr; *ptr2 && !isspace(*ptr2); ptr2++)
@@ -404,12 +420,24 @@
 						ptr2++;
 					
 				}
+				else if (!strncmp(ptr2, "high", 4))
+				{
+					ptr2 += 4;
+					while (*ptr2 && isspace(*ptr2))
+						ptr2++;
+					growsdown = 1;
+				}
 				else
 				{
 					fprintf(stderr, "%s: bad script\n", scriptfile);
 					exit(1);
 				}
 			}
+			else
+			{
+				if (linkscript.nlines > 0)
+					growsdown = linkscript.lines[linkscript.nlines - 1].growsdown;
+			}
 			
 			// now ptr2 points to the load address if there is one
 			// or NUL if not
@@ -417,6 +445,7 @@
 
 			linkscript.lines[linkscript.nlines].noflags = 0;
 			linkscript.lines[linkscript.nlines].yesflags = 0;
+			linkscript.lines[linkscript.nlines].growsdown = growsdown;
 			if (*ptr2)
 				linkscript.lines[linkscript.nlines].loadat = strtol(ptr2, NULL, 16);
 			else
--- a/test/runtests	Mon Aug 05 21:07:14 2019 -0600
+++ b/test/runtests	Mon Aug 05 21:27:09 2019 -0600
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
 #
 # This program will execute all programs in the "tests" directory. Each
 # program is expected to produce output as follows on stdout:
--- a/test/tests/opcodes6809.pl	Mon Aug 05 21:07:14 2019 -0600
+++ b/test/tests/opcodes6809.pl	Mon Aug 05 21:27:09 2019 -0600
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+#!/usr/bin/env perl
 #
 # these tests determine if the opcodes for each instruction, in each
 # addressing mode, are correct.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwar.vcxproj	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwlib.vcxproj">
+      <Project>{93a52e3f-d19d-4a1a-8b8f-15270bd3d0e2}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwar\add.c" />
+    <ClCompile Include="..\lwar\extract.c" />
+    <ClCompile Include="..\lwar\list.c" />
+    <ClCompile Include="..\lwar\lwar.c" />
+    <ClCompile Include="..\lwar\main.c" />
+    <ClCompile Include="..\lwar\remove.c" />
+    <ClCompile Include="..\lwar\replace.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\lwar\lwar.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{D3F0DBD9-6275-428B-950F-01FE32D77A58}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>lwasm</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwasm.vcxproj	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwasm\cycle.c" />
+    <ClCompile Include="..\lwasm\debug.c" />
+    <ClCompile Include="..\lwasm\input.c" />
+    <ClCompile Include="..\lwasm\insn_bitbit.c" />
+    <ClCompile Include="..\lwasm\insn_gen.c" />
+    <ClCompile Include="..\lwasm\insn_indexed.c" />
+    <ClCompile Include="..\lwasm\insn_inh.c" />
+    <ClCompile Include="..\lwasm\insn_logicmem.c" />
+    <ClCompile Include="..\lwasm\insn_rel.c" />
+    <ClCompile Include="..\lwasm\insn_rlist.c" />
+    <ClCompile Include="..\lwasm\insn_rtor.c" />
+    <ClCompile Include="..\lwasm\insn_tfm.c" />
+    <ClCompile Include="..\lwasm\instab.c" />
+    <ClCompile Include="..\lwasm\list.c" />
+    <ClCompile Include="..\lwasm\lwasm.c" />
+    <ClCompile Include="..\lwasm\macro.c" />
+    <ClCompile Include="..\lwasm\main.c" />
+    <ClCompile Include="..\lwasm\os9.c" />
+    <ClCompile Include="..\lwasm\output.c" />
+    <ClCompile Include="..\lwasm\pass1.c" />
+    <ClCompile Include="..\lwasm\pass2.c" />
+    <ClCompile Include="..\lwasm\pass3.c" />
+    <ClCompile Include="..\lwasm\pass4.c" />
+    <ClCompile Include="..\lwasm\pass5.c" />
+    <ClCompile Include="..\lwasm\pass6.c" />
+    <ClCompile Include="..\lwasm\pass7.c" />
+    <ClCompile Include="..\lwasm\pragma.c" />
+    <ClCompile Include="..\lwasm\pseudo.c" />
+    <ClCompile Include="..\lwasm\section.c" />
+    <ClCompile Include="..\lwasm\struct.c" />
+    <ClCompile Include="..\lwasm\symbol.c" />
+    <ClCompile Include="..\lwasm\unicorns.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\lwasm\input.h" />
+    <ClInclude Include="..\lwasm\instab.h" />
+    <ClInclude Include="..\lwasm\lwasm.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwlib.vcxproj">
+      <Project>{93a52e3f-d19d-4a1a-8b8f-15270bd3d0e2}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>lwasm</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwlib.vcxproj	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwlib\lw_alloc.c" />
+    <ClCompile Include="..\lwlib\lw_cmdline.c" />
+    <ClCompile Include="..\lwlib\lw_error.c" />
+    <ClCompile Include="..\lwlib\lw_expr.c" />
+    <ClCompile Include="..\lwlib\lw_free.c" />
+    <ClCompile Include="..\lwlib\lw_realloc.c" />
+    <ClCompile Include="..\lwlib\lw_stack.c" />
+    <ClCompile Include="..\lwlib\lw_string.c" />
+    <ClCompile Include="..\lwlib\lw_stringlist.c" />
+    <ClCompile Include="..\lwlib\lw_win.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\lwlib\lw_alloc.h" />
+    <ClInclude Include="..\lwlib\lw_cmdline.h" />
+    <ClInclude Include="..\lwlib\lw_error.h" />
+    <ClInclude Include="..\lwlib\lw_expr.h" />
+    <ClInclude Include="..\lwlib\lw_stack.h" />
+    <ClInclude Include="..\lwlib\lw_string.h" />
+    <ClInclude Include="..\lwlib\lw_stringlist.h" />
+    <ClInclude Include="..\lwlib\lw_version.h" />
+    <ClInclude Include="..\lwlib\lw_win.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>lwlib</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwlink.vcxproj	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwlib.vcxproj">
+      <Project>{93a52e3f-d19d-4a1a-8b8f-15270bd3d0e2}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwlink\expr.c" />
+    <ClCompile Include="..\lwlink\link.c" />
+    <ClCompile Include="..\lwlink\lwlink.c" />
+    <ClCompile Include="..\lwlink\main.c" />
+    <ClCompile Include="..\lwlink\map.c" />
+    <ClCompile Include="..\lwlink\output.c" />
+    <ClCompile Include="..\lwlink\readfiles.c" />
+    <ClCompile Include="..\lwlink\script.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\lwlink\expr.h" />
+    <ClInclude Include="..\lwlink\lwlink.h" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>lwasm</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwobjdump.vcxproj	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="lwlib.vcxproj">
+      <Project>{93a52e3f-d19d-4a1a-8b8f-15270bd3d0e2}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\lwlink\objdump.c" />
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{852540C9-DEA5-4BFF-BE18-FD946C3857AA}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+    <RootNamespace>lwasm</RootNamespace>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v120</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</OutDir>
+    <IntDir>$(SolutionDir)$(ProjectName)\$(Configuration)\</IntDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../lwlib</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/win/lwtools.sln	Mon Aug 05 21:27:09 2019 -0600
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.31101.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwlib", "lwlib.vcxproj", "{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwasm", "lwasm.vcxproj", "{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwlink", "lwlink.vcxproj", "{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwar", "lwar.vcxproj", "{D3F0DBD9-6275-428B-950F-01FE32D77A58}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lwobjdump", "lwobjdump.vcxproj", "{852540C9-DEA5-4BFF-BE18-FD946C3857AA}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Win32 = Debug|Win32
+		Release|Win32 = Release|Win32
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}.Debug|Win32.Build.0 = Debug|Win32
+		{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}.Release|Win32.ActiveCfg = Release|Win32
+		{93A52E3F-D19D-4A1A-8B8F-15270BD3D0E2}.Release|Win32.Build.0 = Release|Win32
+		{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}.Debug|Win32.Build.0 = Debug|Win32
+		{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}.Release|Win32.ActiveCfg = Release|Win32
+		{52309F4D-C1D8-43FC-BC02-C71B69D01E3B}.Release|Win32.Build.0 = Release|Win32
+		{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}.Debug|Win32.Build.0 = Debug|Win32
+		{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}.Release|Win32.ActiveCfg = Release|Win32
+		{FF4E3359-4B82-4111-8D32-16E0DCFAE39E}.Release|Win32.Build.0 = Release|Win32
+		{D3F0DBD9-6275-428B-950F-01FE32D77A58}.Debug|Win32.ActiveCfg = Debug|Win32
+		{D3F0DBD9-6275-428B-950F-01FE32D77A58}.Debug|Win32.Build.0 = Debug|Win32
+		{D3F0DBD9-6275-428B-950F-01FE32D77A58}.Release|Win32.ActiveCfg = Release|Win32
+		{D3F0DBD9-6275-428B-950F-01FE32D77A58}.Release|Win32.Build.0 = Release|Win32
+		{852540C9-DEA5-4BFF-BE18-FD946C3857AA}.Debug|Win32.ActiveCfg = Debug|Win32
+		{852540C9-DEA5-4BFF-BE18-FD946C3857AA}.Debug|Win32.Build.0 = Debug|Win32
+		{852540C9-DEA5-4BFF-BE18-FD946C3857AA}.Release|Win32.ActiveCfg = Release|Win32
+		{852540C9-DEA5-4BFF-BE18-FD946C3857AA}.Release|Win32.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal