changeset 439:ff4b6095ee72

Bump patch number on gcc6809 patch. The previous update from Brett Gordon <beretta42@gmail.com> updated the gcc6809 patch but didn't update it's patch number tag. Update the tag now.
author William Astle <lost@l-w.ca>
date Tue, 15 Aug 2017 20:49:58 -0600
parents f18cc0c87a7e
children fda62f676ed4
files extra/gcc6809lw-4.6.4-6.patch extra/gcc6809lw-4.6.4-7.patch
diffstat 2 files changed, 8164 insertions(+), 8164 deletions(-) [+]
line wrap: on
line diff
--- a/extra/gcc6809lw-4.6.4-6.patch	Tue Aug 15 20:48:40 2017 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8164 +0,0 @@
-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-7.patch	Tue Aug 15 20:49:58 2017 -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!