/*
 * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 */

rscid = "$Header$"

			/********************************
			 *				*
			 *    68000, 68010 and 68020    *
			 *	      back end table	*
			 *				*
			 ********************************/

#include <whichone.h>

#if TBL68881 && ! TBL68020
Something very wrong here!
#endif
#if WORD_SIZE!=2 && WORD_SIZE!=4
Something very wrong here!
#endif

/* #define	FANCY_MODES	1
/*	On the M68020, there are some real fancy addressing modes.
	Their use makes the code a bit shorter, but also much slower.
	The FANCY_MODES #define enables the use of these addressing
	modes.
*/

#define small(x) ((x)>=1 && (x)<=8)
#define directadd(x)	(small(x) || (x)>128)
#define directsub(x)	(directadd(0-x))
#define nicesize(x) ((x)==1||(x)==2||(x)==4||(x)==8)
#define low8(x) ((x) & 0377)
#define low16(x) ((x) & 0177777)
#define in_1(x) sfit(x,8)
#define in_2(x) sfit(x,16)


EM_WSIZE = WORD_SIZE
EM_PSIZE = 4
EM_BSIZE = 8

SL = 8

TIMEFACTOR = 1/2


PROPERTIES

D_REG			/* data registers */
A_REG(4)		/* address registers */
DD_REG			/* allocatable D_REG, may not be a register variable */
AA_REG(4)		/* allocatable A_REG, may not be a register variable */
RD_REG			/* data register, register var */
RA_REG(4)		/* address register, register var */
#if WORD_SIZE==2
D_REG4(4)		/* data register, 4 bytes */
DD_REG4(4)		/* allocatable D_REG, 4 bytes */
#else
#define D_REG4 D_REG
#define DD_REG4 DD_REG
#endif
#if TBL68881
FS_REG(4)		/* floating point register */
FD_REG(8)		/* double floating point register */
#endif



REGISTERS

d0, d1, d2			:D_REG, DD_REG.
d3, d4, d5, d6, d7		:D_REG, RD_REG regvar.
#if WORD_SIZE==2
dl0("d0")=d0, dl1("d1")=d1, dl2("d2")=d2	:D_REG4, DD_REG4.
#else
#define dl0	d0
#define dl1	d1
#define dl2	d2
#endif
a0, a1				:A_REG, AA_REG.
a2, a3, a4, a5			:A_REG, RA_REG regvar(reg_pointer).
lb ("a6"), sp			:A_REG.	/* localbase and stack pointer */
#if TBL68881
F0 ("fp0"), F1 ("fp1"), F2 ("fp2"), F3 ("fp3"), F4 ("fp4"), F5 ("fp5"),
F6 ("fp6"), F7 ("fp7")		:FS_REG.
fp0=F0,fp1=F1,fp2=F2,fp3=F3,fp4=F4,fp5=F5,fp6=F6,fp7=F7
				:FD_REG.
#endif



TOKENS

	/* Not all addressing modes available on the MC68020 are used in this
	 * table. E.g (Dn), data register indirect is not used. Compared to
	 * (An), address register indirect, (Dn) requires two more bytes and
	 * several more clock cycles. Using (Dn) is even more expensive in
	 * time than first moving Dn to an address register An, and then using
	 * (An). For this kind of reasons several addressing modes are
	 * not used in this table.
	 *
	 * Cost in bytes may sometimes be incorrect. Several effective addresses
	 * use displacements that can occupy either 2 or 4 bytes. These are not
	 * considered different TOKENS in this table.
	 *
	 * Data registers are the only registers used as index registers in this
	 * table; address registers are only used to hold addresses.
	 *
	 * For the m68k2 and m68k4 table: the MC68000 and MC68010 have two
	 * modes that use displacements (offsets) of limited size:
	 * 	- offset(A_REG, Index_reg), where offset is only 8 bits, and
	 *	- offset(A_REG), where offset can only be 16 bits.
	 * To make sure that no output is given with offsets too large, two
	 * extra tokens are declared: t_regAregXcon and t_regAcon. These are
	 * used as addresses to these modes. Whenever the displacements become
	 * too large, they are transformed into different tokens.
	 *
	 * Sometimes some TOKENS are used with displacements (offsets) of 0.
	 * It would have been possible to provide separate TOKENS for these, in
	 * case the assembler doesn't handle zero offsets optimally. This
	 * however would mean a very large amount of extra TOKENS and SETS for
	 * a very small profit in code bytes, so we won't do that.
	 *
	 * To prevent the TOKENS list from getting too unreadable, #ifdefs are
	 * used to form three parts: 
	 *	(i)   the common part;
	 *	(ii)  the m68k2 and m68k4 part;
	 *	(iii) the m68020 part;
	 */

	/* Part (i) */
zero_const	= {INT num;} WORD_SIZE cost(0,0) "#" num .
small_const	= {INT num;} WORD_SIZE cost(0,0) "#" num .
bconst		= {INT num;} WORD_SIZE cost(0,0) "#" num .
const		= {INT num;} WORD_SIZE cost(4,4) "#" num .
#if WORD_SIZE==2
/* ??? "string+const */
zero_const4	= {INT num;} 4 cost(0,0) "#" num .
small_const4	= {INT num;} 4 cost(0,0) "#" num .
bconst4		= {INT num;} 4 cost(0,0) "#" num .
const4		= {ADDR num;} 4 cost(4,4) "#" num .
#endif
indirect4	= {A_REG reg;} 4 cost(0,4) "(" reg ")" .
post_inc4	= {A_REG reg;} 4 cost(0,4) "(" reg ")+" .
pre_dec4	= {A_REG reg;} 4 cost(0,5) "-(" reg ")" .
dreg4		= {D_REG4 reg;} 4 cost(0,0) reg .
areg		= {A_REG reg;} 4 cost(0,0) reg .
dreg2		= {D_REG reg;} WORD_SIZE cost(0,0) reg .
indirect2	= {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")" .
post_inc2	= {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")+" .
pre_dec2	= {A_REG reg;} WORD_SIZE cost(0,5) "-(" reg ")" .
dreg1		= {D_REG reg;} WORD_SIZE cost(0,0) reg .
indirect1	= {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")" .
post_inc1	= {A_REG reg;} WORD_SIZE cost(0,4) "(" reg ")+" .
pre_dec1	= {A_REG reg;} WORD_SIZE cost(0,5) "-(" reg ")" .

ext_addr	= {ADDR bd;} 4 cost(4,5) "#" bd .
llabel		= {ADDR bd;} 4 cost(2,0) bd .
slabel		= {ADDR bd;} 4 cost(0,0) bd .

/* check this out */
extend1		= {D_REG reg;} WORD_SIZE cost(0,0) reg .
#if WORD_SIZE==2
extend1_4	= {D_REG4 reg;} 4 cost(0,0) reg .
#else
#define extend1_4	extend1
#endif
extend2		= {D_REG4 reg;} 4 cost(0,0) reg .

#ifndef TBL68020
	/* Part (ii) */
absolute4	= {ADDR bd;} 4 cost(4,8) bd .
offsetted4	= {A_REG reg; INT bd;} 4 cost(2,6) bd "(" reg ")" .
index_off4	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,7)
			    bd "(" reg "," xreg ".l)" .
absolute2	= {ADDR bd;} WORD_SIZE cost(4,6) bd .
offsetted2	= {A_REG reg; INT bd;} WORD_SIZE cost(2,4) bd "(" reg ")" .
index_off2	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(2,5)
			    bd "(" reg "," xreg ".l)" .
absolute1	= {ADDR bd;} WORD_SIZE cost(4,6) bd .
offsetted1	= {A_REG reg; INT bd;} WORD_SIZE cost(2,4) bd "(" reg ")" .
index_off1	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(2,5)
			    bd "(" reg "," xreg ".l)" .

LOCAL		= {INT bd;} WORD_SIZE cost(2,6) bd "(a6)" .
#if WORD_SIZE==2
/* pointers may go into DLOCAL's */
DLOCAL		= {INT bd;} 4 cost(2,6) bd "(a6)" .
#endif

local_addr	= {INT bd;} 4 cost(2,6) bd "(a6)" .
regAcon		= {A_REG reg; INT bd;} 4 cost(2,6) bd "(" reg ")" .
regAregXcon	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,8)
				bd "(" reg "," xreg ".l)" .
			/* note: in the m68k[24] version %sc always equals 1 */

t_regAregXcon	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,8) .
t_regAcon	= {A_REG reg; INT bd;} 4 cost(2,6) .

#else /* TBL68020 */
	/* Part (iii) */
absolute4	= {ADDR bd;} 4 cost(4,7) "(" bd ")" .
offsetted4	= {A_REG reg; INT bd;} 4 cost(2,6) "(" bd "," reg ")" .
index_off4	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(4,9)
			    "(" bd "," reg "," xreg ".l*" sc ")" .
abs_index4	= {INT sc; D_REG4 xreg; ADDR bd;} 4 cost(6,9)
			    "(" bd "," xreg ".l*" sc ")" .
OFF_off4	= {A_REG reg; INT bd; ADDR od;} 4 cost(6,19)
			    "([" bd "," reg "]," od ")" .
OFF_indoff4	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,19)
			    "([" bd "," reg "]," xreg ".l*" sc "," od ")" .
INDOFF_off4	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,19)
			    "([" bd "," reg "," xreg ".l*" sc "]," od ")" .
ABS_off4	= {ADDR bd; ADDR od;} 4 cost(8,22) "([" bd "]," od ")" .
ABS_indoff4	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,22)
			    "([" bd "]," xreg ".l*" sc "," od ")" .
ABSIND_off4	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,22)
			    "([" bd "," xreg ".l*" sc "]," od ")" .

absolute2	= {ADDR bd;} WORD_SIZE cost(4,7) "(" bd ")" .
offsetted2	= {A_REG reg; INT bd;} WORD_SIZE cost(2,6) "(" bd "," reg ")" .
index_off2	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(4,9)
			    "(" bd "," reg "," xreg ".l*" sc ")" .
abs_index2	= {INT sc; D_REG4 xreg; ADDR bd;} WORD_SIZE cost(6,9)
			    "(" bd "," xreg ".l*" sc ")" .
OFF_off2	= {A_REG reg; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "]," od ")" .
OFF_indoff2	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "]," xreg ".l*" sc "," od ")" .
INDOFF_off2	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "," xreg ".l*" sc "]," od ")" .
ABS_off2	= {ADDR bd; ADDR od;} WORD_SIZE cost(8,22) "([" bd "]," od ")" .
ABS_indoff2	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
			    "([" bd "]," xreg ".l*" sc "," od ")" .
ABSIND_off2	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
			    "([" bd "," xreg ".l*" sc "]," od ")" .

absolute1	= {ADDR bd;} WORD_SIZE cost(4,7) "(" bd ")" .
offsetted1	= {A_REG reg; INT bd;} WORD_SIZE cost(2,6) "(" bd "," reg ")" .
index_off1	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} WORD_SIZE cost(4,9)
			    "(" bd "," reg "," xreg ".l*" sc ")" .
abs_index1	= {INT sc; D_REG4 xreg; ADDR bd;} WORD_SIZE cost(6,9)
			    "(" bd "," xreg ".l*" sc ")" .
OFF_off1	= {A_REG reg; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "]," od ")" .
OFF_indoff1	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "]," xreg ".l*" sc "," od ")" .
INDOFF_off1	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} WORD_SIZE cost(6,19)
			    "([" bd "," reg "," xreg ".l*" sc "]," od ")" .
ABS_off1	= {ADDR bd; ADDR od;} WORD_SIZE cost(8,22) "([" bd "]," od ")" .
ABS_indoff1	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
			    "([" bd "]," xreg ".l*" sc "," od ")" .
ABSIND_off1	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} WORD_SIZE cost(8,22)
			    "([" bd "," xreg ".l*" sc "]," od ")" .

LOCAL		= {INT bd;} WORD_SIZE cost(2,6) "(" bd ",a6)" .
#if WORD_SIZE==2
/* pointers may go into DLOCAL's */
DLOCAL		= {INT bd;} 4 cost(2,6) "(" bd ",a6)" .
#endif
ILOCAL		= {INT bd;} WORD_SIZE cost(4,16) "([" bd ",a6])" .

/* check this out !!! ??? */
local_addr	= {INT bd;} 4 cost(2,3) "(" bd ",a6)" .
regAcon		= {A_REG reg; INT bd;} 4 cost(2,3) "(" bd "," reg ")" .
regAregXcon	= {A_REG reg; D_REG4 xreg; INT sc; INT bd;} 4 cost(2,7)
				"(" bd "," reg "," xreg ".l*" sc ")" .
off_con		= {A_REG reg; INT bd; ADDR od;} 4 cost(6,18)
				"([" bd "," reg "]," od ")".
off_regXcon	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,18)
				"([" bd "," reg "]," xreg ".l*" sc "," od ")" .
indoff_con	= {A_REG reg; D_REG4 xreg; INT sc; INT bd; ADDR od;} 4 cost(6,18)
				"([" bd "," reg "," xreg ".l*" sc "]," od ")" .
abs_con		= {ADDR bd; ADDR od;} 4 cost(8,21) "([" bd "]," od ")" .
abs_regXcon	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,21)
				"([" bd "]," xreg ".l*" sc "," od ")" .
absind_con	= {INT sc; D_REG4 xreg; ADDR bd; ADDR od;} 4 cost(8,21)
				"([" bd "," xreg ".l*" sc "]," od ")" .
ext_regX	= {INT sc; D_REG4 xreg; ADDR bd;} 4 cost(6,15)
				"(" bd "," xreg ".l*" sc ")" .

regX		= {INT sc; D_REG4 xreg;} 4 cost(2,7) "(" xreg ".l*" sc ")" .
DREG_pair	= {D_REG4 reg1; D_REG4 reg2;} 8 cost(2,0) reg1 ":" reg2 .

#define	t_regAregXcon	regAregXcon
#define t_regAcon	regAcon

#endif /* TBL68020 */

#if WORD_SIZE!=2
#define DLOCAL LOCAL
#endif

SETS

		/* The SETS list cannot be kept as 'readable' as the TOKENS
		 * list because cgg is one pass.
		 * We makes use of the fact that sets are indeed sets. Thus
		 * D_REG + D_REG4 == D_REG, when the wordsize is 4.
		 */

sconsts		= small_const + bconst .
consts		= const + sconsts + zero_const.
#if WORD_SIZE!=2
#define small_const4	small_const
#define zero_const4	zero_const
#define bconst4		bconst
#define const4		const
#define sconsts4	sconsts
#define consts4		consts
#else
sconsts4	= small_const4 + bconst4 .
consts4		= const4 + sconsts4 + zero_const4.
#endif

#ifndef TBL68020
	/* A m68k2/m68k4 part */
data4		= D_REG4 + DLOCAL + consts4 + post_inc4 + pre_dec4 +
		  indirect4 + offsetted4 + index_off4 + absolute4 +
		  ext_addr + dreg4 .
memory4		= data4 - D_REG4 - dreg4 .
control4	= indirect4 + offsetted4 + index_off4 + absolute4 +
		  DLOCAL.
alterable4	= data4 + A_REG - consts4 - ext_addr .
any4		= data4 + A_REG . /* all four above together */

#if WORD_SIZE==2
data2		= D_REG + LOCAL + dreg2 + post_inc2 + pre_dec2 +
		  indirect2 + offsetted2 + index_off2 + absolute2 +
		  consts .
memory2		= data2 - D_REG - dreg2 .
control2	= indirect2 + offsetted2 + index_off2 + absolute2 + LOCAL.
#else
data2		= dreg2 + post_inc2 + pre_dec2 + indirect2 +
		  offsetted2 + index_off2 + absolute2 + consts .
memory2		= data2 - dreg2 .
control2	= indirect2 + offsetted2 + index_off2 + absolute2 .
#endif
alterable2	= data2 + D_REG - consts .
any2		= data2 + D_REG .

data1		= dreg1 + post_inc1 + pre_dec1 + indirect1 +
		  offsetted1 + index_off1 + absolute1 + consts .
memory1		= data1 - dreg1 .
control1	= indirect1 + offsetted1 + index_off1 + absolute1 .
alterable1	= data1 + D_REG - consts .
any1		= data1 + D_REG .

#else /* TBL68020 */

data4		= D_REG4 + indirect4 + post_inc4 + pre_dec4 + index_off4 +
		  offsetted4 + OFF_off4 + OFF_indoff4 +
		  INDOFF_off4 + dreg4 +
		  ABS_off4 + ABS_indoff4 + ABSIND_off4 +
		  absolute4 + abs_index4 + consts4 + ext_addr +
		  DLOCAL
#if WORD_SIZE!=2
		  + ILOCAL
#endif
		  .
memory4		= data4 - D_REG4 - dreg4 .
control4	= memory4 - (post_inc4 + pre_dec4 + consts4 + ext_addr).
alterable4	= data4 + A_REG - consts - ext_addr .
any4		= data4 + A_REG . /* all four above together */

#if WORD_SIZE==2
data2		= D_REG + LOCAL+ ILOCAL+
		    dreg2 + indirect2 + post_inc2 + pre_dec2 + index_off2 +
		      offsetted2 + OFF_off2 + OFF_indoff2 +
		  INDOFF_off2 +
		  ABS_off2 + ABS_indoff2 + ABSIND_off2 +
		  absolute2 + abs_index2 + consts .
memory2		= data2 - D_REG - dreg2 .
#else
data2		= dreg2 + indirect2 + post_inc2 + pre_dec2 + index_off2 +
		      offsetted2 + OFF_off2 + OFF_indoff2 +
		  INDOFF_off2 +
		  ABS_off2 + ABS_indoff2 + ABSIND_off2 +
		  absolute2 + abs_index2 + consts .
memory2		= data2 - dreg2 .
#endif
control2	= memory2 - (post_inc2 + pre_dec2 + consts ) .
alterable2	= data2 + D_REG - consts .
any2		= data2 + D_REG. /* all four above together */

data1		= dreg1 + indirect1 + post_inc1 + pre_dec1 + index_off1 +
		      offsetted1 + OFF_off1 + OFF_indoff1 +
		  INDOFF_off1 +
		  ABS_off1 + ABS_indoff1 + ABSIND_off1 +
		  absolute1 + abs_index1 + consts .
memory1		= data1 - dreg1 .
control1	= memory1 - (post_inc1 + pre_dec1 + consts ) .
alterable1	= data1 + D_REG - consts .
any1		= data1 + D_REG. /* all four above together */

#endif /* TBL68020 */
	/* This is a common part */
#if WORD_SIZE==2
/* Not any4, since any is used in 'with' and not in 'kills' */
any		= any2 + any1 .
#else
any		= any4 + any2 + any1 .
#endif
control		= control4 + control2 + control1 .
indirect	= indirect4 + indirect2 + indirect1 .
offsetted	= offsetted4 + offsetted2 + offsetted1 .
index_off	= index_off4 + index_off2 + index_off1 .
absolute	= absolute4 + absolute2 + absolute1 .
pre_post	= pre_dec4 + pre_dec2 + pre_dec1 +
		  post_inc4 + post_inc2 + post_inc1 .

#ifndef TBL68020
	/* A m68k2/m68k4 part */
regind_addr	= regAcon + regAregXcon + t_regAcon + t_regAregXcon .
address		= ext_addr + local_addr + regAcon + regAregXcon .
all_regind	= indirect + offsetted + pre_post + index_off +
		      regind_addr + areg .
all_indir	= all_regind .
allexceptcon	= ALL - ( D_REG + A_REG + consts + dreg2 + dreg1 +
		    local_addr + ext_addr + regAcon + regAregXcon +
		    t_regAcon + t_regAregXcon ) .
use_index	= index_off4 + index_off2 + index_off1 .

#else /* TBL68020 */

reg_memind4	= OFF_off4 + OFF_indoff4 + INDOFF_off4 .
memind4		= reg_memind4 +
		  ABS_off4 + ABS_indoff4 .
reg_memind2	= OFF_off2 + OFF_indoff2 + INDOFF_off2 .
memind2		= reg_memind2 +
		  ABS_off2 + ABS_indoff2 .
reg_memind1	= OFF_off1 + OFF_indoff1 + INDOFF_off1 .
memind1		= reg_memind1 +
		  ABS_off1 + ABS_indoff1 .
reg_memind	= reg_memind4 + reg_memind2 + reg_memind1 .
memind		= memind4 + memind2 + memind1 .
regind_addr	= regAcon + regAregXcon +
		  off_con + off_regXcon +
		  indoff_con .
address		= regind_addr +
		  ext_addr + local_addr +
		  abs_con + abs_regXcon +
		  absind_con +
		  ext_regX .
all_regind	= indirect + offsetted + index_off + pre_post +
		      reg_memind + regind_addr + areg .
all_indir	= all_regind + memind + ILOCAL .
allexceptcon	= ALL - ( D_REG + A_REG + consts + dreg2 + dreg1 +
		    local_addr + ext_addr + regAcon + regAregXcon + ext_regX ) .
use_index4	= index_off4 + abs_index4 +
		  OFF_indoff4 + INDOFF_off4 +
		  ABS_indoff4 + ABSIND_off4 .
use_index2	= index_off2 + abs_index2 +
		  OFF_indoff2 + INDOFF_off2 +
		  ABS_indoff2 + ABSIND_off2 .
use_index1	= index_off1 + abs_index1 +
		  OFF_indoff1 + INDOFF_off1 +
		  ABS_indoff1 + ABSIND_off1 .
use_indaddr	= regAregXcon + 
		  off_regXcon + indoff_con +
		  abs_regXcon + absind_con +
		  ext_regX .

use_index	= use_index4 + use_index2 + use_index1 + use_indaddr + regX .

#endif /* TBL68020 */
	/* A common part */
posextern	= absolute + all_indir .

#if WORD_SIZE==2
genreg2		= D_REG .
#define genreg	genreg2
#else
#define genreg	genreg4
#endif
genreg4		= D_REG4 + A_REG.
label		= llabel + slabel .
immediate4	= consts4 + ext_addr .
#if WORD_SIZE==2
immediate2	= consts .
#endif
conreg4		= D_REG4 + immediate4 .
conreg2		= dreg2 + consts + D_REG .
conreg1		= dreg1 + consts + D_REG .
#if WORD_SIZE==2
conreg		= conreg1 + conreg2 .
#else
conreg		= conreg1 + conreg2 + conreg4 .
#endif
shconreg	= D_REG + small_const .
datalt4		= data4 * alterable4 .
datalt2		= data2 * alterable2 .
datalt1		= data1 * alterable1 .
datalt		= datalt4 + datalt2 + datalt1 .
memalt4		= memory4 * alterable4 .
memalt2		= memory2 * alterable2 .
memalt1		= memory1 * alterable1 .

#ifndef TBL68020
	/* A m68k2/m68k4 part */
imm_cmp4	= alterable4 - A_REG .
imm_cmp2	= alterable2 + D_REG .
imm_cmp1	= datalt1 + D_REG .

test_set4	= datalt4 + extend2 + extend1_4 .
#if WORD_SIZE==2
test_set2	= datalt2 + extend1 .
#else
test_set2	= datalt2 .
#endif
test_set1	= datalt1 .

#else /* TBL68020 */

imm_cmp4	= any4 - immediate4 - A_REG .
imm_cmp2	= any2 - consts .
imm_cmp1	= any1 - consts .

test_set4	= any4 - immediate4 + extend2 + extend1_4 .
#if WORD_SIZE==2
test_set2	= data2 + extend1 - immediate2 .
#else
test_set2	= data2 - consts .
#endif
test_set1	= data1 - consts .

#endif /* TBL68020 */

test_set	= test_set4 + test_set2 + test_set1 .

#ifndef TBL68020
t_address	= address + t_regAregXcon + t_regAcon .
#else /* TBL68020 */
#define	t_address	address
#endif /* TBL68020 */

#if TBL68881
freg		= FD_REG + FS_REG .
store4		= any4 + FS_REG .
#else
store4		= any4 .
#endif
#if WORD_SIZE==2
dups2		= genreg2 .
#endif
dups4		= genreg4 .

#include	"instrmacs.h"

INSTRUCTIONS

	/* Since the 68000 , the 68010 and the 68020 instruction sets are rather
	 * extensive, especially because e.g. 'add.l' and 'add.w' are
	 * considered different instructions, only those instructions are
	 * listed here that are used in the rest of this table.
	 *
	 * Instruction timing cost cannot be accurately given, nor the timing
	 * cost for getting operands. Detailed information about this can be
	 * found in the "MC68020 User's Manual", section 9, about instruction
	 * timing. The cost used in this table are 'worst case' cost, as
	 * mentioned in section 9 of the user's manual. Furthermore, the
	 * timing information for the 68k[24] and the 68020 differ, which
	 * means that the 68k[24] will not always have the best code
	 * possible.
	 *
	 * The first few instructions had to be added because register
	 * variables are used. The LOCALs below are register variables.
	 * One may not conclude that these operations are also allowed
	 * on LOCALs that are not register variables.
	 * The cost have been adapted, but are not accurate; when 'real'
	 * LOCALs are used the cost are very inaccurate.
	 */

add_i  ADD_I	any_int:ro,	LOCAL:rw:cc		cost(0,0).
sub_i  SUB_I	any_int:ro,	LOCAL:rw:cc		cost(0,0).
lea		address:ro,	DLOCAL:wo		cost(0,0).
sh   "illegal"	shconreg+LOCAL:ro,	LOCAL:rw:cc		cost(0,0).
xxx  "illegal"	data4:ro,	LOCAL:rw:cc		cost(0,0).
xxx  "illegal"	LOCAL:ro,	alterable4:rw:cc	cost(0,0).
#if WORD_SIZE==2
/* divs_w "divs.w" data2:ro,	LOCAL:rw:cc		cost(0,56). */
/* divu_w "divu.w" data2:ro,	LOCAL:rw:cc		cost(0,44). */
muls_w "muls.w" data2:ro,	LOCAL:rw:cc		cost(0,28).
mulu_w "mulu.w" data2:ro,	LOCAL:rw:cc		cost(0,28).
#endif
#if TBL68020 && WORD_SIZE!=2
divs_l "divs.l" data4:ro,	LOCAL:rw:cc		cost(0,90).
divu_l "divu.l" data4:ro,	LOCAL:rw:cc		cost(0,78).
muls_l "muls.l" data4:ro,	LOCAL:rw:cc		cost(0,44).
mulu_l "mulu.l" data4:ro,	LOCAL:rw:cc		cost(0,44).
#endif /* TBL68020 */

#if WORD_SIZE==2
add_l  "add.l"	any4:ro,	D_REG4:rw:cc		cost(2,3).
#else
add_l  "add.l"	any4:ro,	D_REG+LOCAL:rw:cc	cost(2,3).
#endif
add_l  "add.l"	any4:ro,	A_REG+DLOCAL+areg:rw	cost(2,3).
add_l  "add.l"	conreg4:ro,	alterable4:rw:cc	cost(2,6).
#if WORD_SIZE==2
add_w  "add.w"	any2:ro,	D_REG+LOCAL:rw:cc	cost(2,3).
add_w  "add.w"	conreg2:ro,	alterable2:rw:cc	cost(2,6).
#endif
and_l  "and.l"	data4:ro,	D_REG4:rw:cc		cost(2,3).
and_l  "and.l"	D_REG4:ro,	memalt4:rw:cc		cost(2,6).
and_l  "and.l"	consts4:ro,	datalt4:rw:cc		cost(2,6).
#if WORD_SIZE==2
and_w  "and.w"	data2:ro,	D_REG:rw:cc		cost(2,3).
and_w  "and.w"	D_REG:ro,	memalt2:rw:cc		cost(2,6).
and_w  "and.w"	consts:ro,	datalt2:rw:cc		cost(2,6).
#endif
asl_l  "asl.l"	shconreg:ro,	D_REG4:rw:cc		cost(2,5).
asl   "asl #1,"	memalt2:rw:cc				cost(2,4).
asr_l  "asr.l"	shconreg:ro,	D_REG4:rw:cc		cost(2,4).
asr   "asr #1,"	memalt2:rw:cc				cost(2,4).
#if WORD_SIZE==2
asl_w  "asl.w"	shconreg:ro,	D_REG:rw:cc		cost(2,5).
asr_w  "asr.w"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
#endif
bclr		const:ro,	D_REG:rw kills:cc	cost(2,4).
bra		label					cost(2,5).
bcc		label					cost(2,5).
bcs		label					cost(2,5).
beq		label					cost(2,5).
bge		label					cost(2,5).
bgt		label					cost(2,5).
bhi		label					cost(2,5).
ble		label					cost(2,5).
bls		label					cost(2,5).
blt		label					cost(2,5).
bmi		label					cost(2,5).
bne		label					cost(2,5).
bpl		label					cost(2,5).
bvc		label					cost(2,5).
bvs		label					cost(2,5).
bset		conreg2:ro,	D_REG+D_REG4:rw kills :cc	cost(2,4).
btst		conreg2:ro,	any1:rw kills :cc	cost(2,3).
/* Check dreg[21] for m68020 and m68k2 */
clr_l  "clr.l"	D_REG4+dreg4:wo:cc			cost(2,3).
clr_l  "clr.l"	memalt4:wo:cc				cost(2,6).
clr_w  "clr.w"	D_REG+dreg2:wo:cc			cost(2,2).
clr_w  "clr.w"	memalt2:wo:cc				cost(2,4).
clr_b  "clr.b"	D_REG+dreg1:wo:cc			cost(2,2).
clr_b  "clr.b"	memalt1:wo:cc				cost(2,4).
cmp_l  "cmp.l"	any4:ro,	genreg4:ro kills :cc	cost(2,3).
cmp_l  "cmp.l"	post_inc4:ro,	post_inc4:ro kills :cc 	cost(2,2).
cmp_l  "cmp.l"	immediate4:ro,	imm_cmp4:ro kills :cc	cost(2,2).
#if WORD_SIZE==2
cmp_w  "cmp.w"	any2+extend2:ro,	D_REG+dreg2+extend2:ro kills :cc	cost(2,2).
#else
cmp_w  "cmp.w"	any2+extend2:ro,	dreg2+extend2:ro kills :cc	cost(2,2).
#endif
cmp_w  "cmp.w"	post_inc2:ro,	post_inc2:ro kills :cc 	cost(2,2).
cmp_w  "cmp.w"	consts:ro,	imm_cmp2:ro kills :cc	cost(2,2).
cmp_b  "cmp.b"	any1+extend1+extend1_4:ro,	dreg1+extend1+extend1_4:ro kills :cc	cost(2,3).
cmp_b  "cmp.b"	post_inc1:ro,	post_inc1:ro kills :cc 	cost(2,2).
cmp_b  "cmp.b"	consts:ro,	imm_cmp1:ro kills :cc	cost(2,2).
dbf		D_REG4:rw,	label			cost(2,5).
eor_l  "eor.l"	conreg4:ro,	datalt4:rw:cc		cost(2,6).
#if WORD_SIZE==2
eor_w  "eor.w"	conreg2:ro,	datalt2:rw:cc		cost(2,4).
#endif
/* in the next two instructions: LOCAL only allowed if register var */
ext_l  "ext.l"	D_REG+LOCAL+D_REG4:rw:cc		cost(2,2).
ext_w  "ext.w"	D_REG+LOCAL+D_REG4:rw:cc		cost(2,2).
jmp		address+control4			cost(2,0).
jsr		address+control4 kills :cc d0 d1 d2 a0 a1 cost(2,3).
lea		address+control4:ro, A_REG+areg:wo	cost(2,0).
/*
lsl_l  "lsl.l"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
lsl   "lsl #1,"	memalt2:rw:cc				cost(2,4).
*/
lsr_l  "lsr.l"	shconreg:ro,	D_REG4:rw:cc		cost(2,4).
#if WORD_SIZE==2
lsr_w  "lsr.w"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
#endif
lsr   "lsr #1,"	memalt2:rw:cc				cost(2,4).
/* move_l does not set the condition codes if the destination is an
   address register!
*/
move_l "move.l" any4:ro,	A_REG+areg:wo		cost(2,2).
move_l "move.l" any4:ro,	alterable4+dreg4-(areg+A_REG):wo:cc	cost(2,2).
#if WORD_SIZE==2
move_l "move.l" sconsts:ro,	D_REG+dreg2:wo:cc	cost(2,2).
/*
move_l "move.l" any2:ro,	alterable4+dreg4-(areg+A_REG):wo:cc	cost(2,2).
*/
move_w "move.w" any2:ro,	alterable2+dreg2:wo:cc	cost(2,2).
move_b "move.b" any1:ro,	alterable1+dreg2:wo:cc	cost(2,2).
#else
move_w "move.w" any2:ro,	alterable2+dreg4:wo:cc	cost(2,2).
move_b "move.b" any1:ro,	alterable1+dreg4:wo:cc	cost(2,2).
#endif
neg_b  "neg.b"	D_REG:rw:cc			cost(2,3).
neg_w  "neg.w"	D_REG:rw:cc			cost(2,3).
neg_l  "neg.l"	D_REG4:rw:cc				cost(2,3).
neg_l  "neg.l"	memory4:rw:cc				cost(2,6).
#if WORD_SIZE==2
neg_w  "neg.w"	memory2:rw:cc				cost(2,6).
#endif
not_l  "not.l"	D_REG4:rw:cc				cost(2,3).
not_l  "not.l"	memory4:rw:cc				cost(2,6).
#if WORD_SIZE==2
not_w  "not.w"	D_REG:rw:cc				cost(2,3).
not_w  "not.w"	memory2:rw:cc				cost(2,6).
#endif
or_l   "or.l"	data4:ro,	D_REG4:rw:cc		cost(2,3).
or_l   "or.l"	D_REG4:ro,	memalt4:rw:cc		cost(2,6).
or_l   "or.l"	consts4:ro,	datalt4:rw:cc		cost(2,6).
#if WORD_SIZE==2
or_w   "or.w"	data2:ro,	D_REG:rw:cc		cost(2,3).
or_w   "or.w"	D_REG:ro,	memalt2:rw:cc		cost(2,6).
or_w   "or.w"	consts:ro,	datalt2:rw:cc		cost(2,6).
#endif
rol_l  "rol.l"	shconreg:ro,	D_REG4:rw:cc		cost(2,4).
rol   "rol #1,"	memalt2:rw:cc				cost(2,4).
ror_l  "ror.l"	shconreg:ro,	D_REG4:rw:cc		cost(2,4).
ror   "ror #1,"	memalt2:rw:cc				cost(2,4).
#if WORD_SIZE==2
rol_w  "rol.w"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
ror_w  "ror.w"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
#endif
roxl "roxl #1,"	memalt2:rw:cc				cost(2,4).
roxr "roxr #1,"	memalt2:rw:cc				cost(2,4).
sne		datalt1:rw				cost(2,3).
sub_l  "sub.l"	any4:ro,	D_REG4:rw:cc		cost(2,3).
sub_l  "sub.l"	any4+areg:ro,	A_REG+areg:rw		cost(2,3).
sub_l  "sub.l"	conreg4:ro,	alterable4:rw:cc	cost(2,6).
#if WORD_SIZE==2
sub_w  "sub.w"	any2:ro,	D_REG+LOCAL:rw:cc	cost(2,3).
sub_w  "sub.w"	conreg2:ro,	alterable2:rw:cc	cost(2,6).
/* On a swap, we only want the lower part of D_REG, so don't set cc */
swap		D_REG:rw kills :cc			cost(2,2).
#endif
tst_l  "tst.l"	test_set4:ro:cc				cost(2,3).
tst_w  "tst.w"	test_set2+extend2:ro:cc			cost(2,3).
tst_b  "tst.b"	test_set1+extend1+extend1_4:ro:cc	cost(2,3).
unlk		A_REG					cost(2,6).

bxx  "illegal"	label					cost(2,5).
sxx  "illegal"	any_int:wo				cost(2,5).
#if WORD_SIZE==2
s4xx  "illegal"	any4:wo					cost(2,5).
xxx  "illegal"	any4+any2:ro,	any4+any2:rw:cc		cost(2,3).
bit  "illegal"	control4+control2:rw:cc			cost(2,6).
#else
xxx  "illegal"	any4:ro,	any4:rw:cc		cost(2,3).
bit  "illegal"	control4:rw:cc				cost(2,6).
#endif
sh   "illegal"	shconreg:ro,	D_REG:rw:cc		cost(2,4).
shw  "illegal"	control2:rw:cc				cost(2,4).

#if WORD_SIZE==2
divs_w "divs.w" data2:ro,	D_REG:rw:cc		cost(0,56).
divu_w "divu.w" data2:ro,	D_REG:rw:cc		cost(0,44).
muls_w "muls.w" data2:ro,	D_REG:rw:cc		cost(0,28).
mulu_w "mulu.w" data2:ro,	D_REG:rw:cc		cost(0,28).
#endif
#ifdef TBL68020
cmp2_l "cmp2.l" address+control4:ro, genreg4:ro kills :cc cost(2,18).
divs_l "divs.l" data4:ro,	D_REG4:rw:cc		cost(2,90).
divu_l "divu.l" data4:ro,	D_REG4:rw:cc		cost(2,78).
divsl_l "divsl.l" data4:ro,	DREG_pair:rw kills :cc	cost(2,90).
divul_l "divul.l" data4:ro,	DREG_pair:rw kills :cc	cost(2,78).
pea		address+control4+regX			cost(2,4).
#if WORD_SIZE==2
cmp2_w "cmp2.w" address+control2:ro, genreg2:ro kills :cc cost(2,18).
extb_l "extb.l" extend1_4+D_REG4:rw:cc				cost(2,4).
muls_l "muls.l" data4:ro,	D_REG4:rw:cc		cost(2,44).
mulu_l "mulu.l" data4:ro,	D_REG4:rw:cc		cost(2,44).
#else
/* in the next instruction: LOCAL only allowed if register var */
extb_l "extb.l" extend1_4+D_REG+LOCAL:rw:cc			cost(2,4).
muls_l "muls.l" data4:ro,	D_REG+LOCAL:rw:cc		cost(2,44).
mulu_l "mulu.l" data4:ro,	D_REG+LOCAL:rw:cc		cost(2,44).
#endif
#else /* TBL68020 */
pea		address+control4			cost(2,4).
#endif /* TBL68020 */

	/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	 * Extra pseudo instruction; it just kills a D_REG;
	 * it is necessary with long divides where remainders are important;
	 * see also: 'pat rmi' and 'pat rmu'
	 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
killreg "! kill" D_REG+D_REG4+A_REG:wo		cost(0,0).
killcc "! killcc" 	kills :cc			cost(0,0).
#if TBL68881
/* These descriptions are not very accurate, because we have no
   other 8-byte objects in the table.
 */
fmove_s "fmove.s" data4:ro, freg:wo			cost(4,100).
fmove_s "fmove.s" freg:ro, data4:wo			cost(4,100).
fmove_d "fmove.d" freg:ro, data4:wo			cost(4,100).
fmove_d "fmove.d" data4:ro, freg:ro			cost(4,100).
fmove_l "fmove.l" freg:ro, D_REG:wo			cost(4,100).
fmove_l "fmove.l" data4:ro, freg:wo			cost(4,100).
fmove freg:ro,freg:wo					cost(4,100).
fadd_s "fadd.s" data4:ro, freg:rw			cost(4,100).
fadd_d "fadd.d" data4:ro, freg:rw			cost(4,100).
fsub_s "fsub.s" data4:ro, freg:rw			cost(4,100).
fsub_d "fsub.d" data4:ro, freg:rw			cost(4,100).
fsub freg:ro, freg:rw					cost(4,100).
fmul freg:ro, freg:rw					cost(4,100).
fmul_s "fmul.s" data4:ro, freg:rw			cost(4,100).
fmul_d "fmul.d" data4:ro, freg:rw			cost(4,100).
fdiv freg:ro, freg:rw					cost(4,100).
fdiv_s "fdiv.s" data4:ro, freg:rw			cost(4,100).
fdiv_d "fdiv.d" data4:ro, freg:rw			cost(4,100).
fcmp freg:ro, freg:ro					cost(4,100).
fbeq label:ro						cost(4,4).
fblt label:ro						cost(4,4).
fmovecr const:ro, freg:rw				cost(4,100).
fabs freg:rw						cost(4,100).
fneg freg:rw						cost(4,100).
fgetman freg:rw						cost(4,100).
fintrz freg:ro, freg:wo					cost(4,100).
fgetexp freg:ro, freg:wo				cost(4,100).
fsub_l "fsub.l" const:ro, freg:rw			cost(4,100).
#endif


MOVES

from consts %num==0 to D_REG4+dreg4
    gen clr_l %2

#if WORD_SIZE==2
from zero_const4 %num==0 to A_REG+areg
    gen sub_l %2,%2

from zero_const4 %num==0 to D_REG4+dreg4
    gen clr_l %2
#endif

from consts %num==0 to A_REG+areg
    gen sub_l %2,%2

#if WORD_SIZE==2
from consts %num==0 to D_REG+dreg2
    gen clr_w %2

from sconsts to D_REG+dreg2
    gen move_l %1,%2				/* uses moveq */

from consts to D_REG4+dreg4
    gen move_l {const4, %1.num},%2
#endif

#if WORD_SIZE==2
from sconsts4+zero_const4 %num==0 to memalt4
#else
from consts %num==0 to memalt4
#endif
    gen clr_l %2

from consts %num==0 to memalt2
    gen clr_w %2

from consts %num==0 to memalt1
    gen clr_b %2

from consts to memalt1
    gen move_b {const, low8(%1.num)}, %2

#if WORD_SIZE!=2
from consts to memalt2
    gen move_w {const, low16(%1.num)}, %2
#endif

from regAcon %bd==0 to A_REG+areg
    gen move_l %1.reg, %2

#ifndef TBL68020
from t_regAregXcon sfit(%bd, 8) to A_REG+areg
    gen lea {regAregXcon, %1.reg, %1.xreg, 1, %1.bd}, %2

from t_regAregXcon to A_REG+areg
    gen lea {regAregXcon, %1.reg, %1.xreg, 1, 0}, %2
	add_l {const4, %1.bd}, %2

from t_regAcon sfit(%bd, 16) to A_REG+areg
    gen lea {regAcon, %1.reg, %1.bd}, %2

from t_regAcon to A_REG+areg
    gen move_l %1.reg, %2
	add_l {const4, %1.bd}, %2
#endif /* TBL68020 */

from address - ext_addr to A_REG+areg
    gen lea %1, %2

#if WORD_SIZE==2
from ext_addr to A_REG+areg
    gen lea {absolute4, %1.bd}, %2
#endif

from any4 to areg+A_REG
    gen move_l %1, %2

from any4 to alterable4-(areg+A_REG)
    gen move_l %1, %2

from any2 to alterable2
    gen move_w %1, %2

from any1 to alterable1
    gen move_b %1, %2

#if WORD_SIZE!=2
from any4-sconsts4 to A_REG+areg
    gen move_l %1, %2

from any2 to dreg4
    gen clr_l %2
	move_w %1, %2
#endif

from any1 to dreg_int
    gen clr_i %2
	move_b %1, %2

#if WORD_SIZE==2
from any1 to dreg2
    gen clr_w %2
	move_b %1, %2
#endif

#if TBL68881
from data4 to FS_REG
    gen fmove_s %1, %2

from FS_REG to datalt4
    gen fmove_s %1, %2
#endif

TESTS

/* For the 68020 and m68k4, the extend1_4 will be extend1 */
to test test_set4-(extend2+extend1+extend1_4)
    gen tst_l %1

to test test_set2+extend2
    gen tst_w %1

to test test_set1+extend1+extend1_4
    gen tst_b %1


STACKINGRULES


#if WORD_SIZE!=2
from consts %num==0 to STACK
    gen clr_l {pre_dec4, sp}
#else
from zero_const4 to STACK
    gen clr_l {pre_dec4, sp}
from consts %num==0 to STACK
    gen clr_w {pre_dec2, sp}
#endif

#ifndef TBL68020
from t_regAregXcon sfit(%bd, 8) to STACK
    gen pea {regAregXcon, %1.reg, %1.xreg, 1, %1.bd}

from t_regAregXcon to STACK
    gen pea {regAregXcon, %1.reg, %1.xreg, 1, 0}
	add_l {const4, %1.bd}, {indirect4, sp}

from t_regAcon sfit(%bd, 16) to STACK
    gen pea {regAcon, %1.reg, %1.bd}

from t_regAcon to STACK
    gen move_l %1.reg, {pre_dec4, sp}
	add_l {const4, %1.bd}, {indirect4, sp}
#endif /* TBL68020 */

from A_REG to STACK
    gen pea {indirect4, %1}

from address - ext_addr to STACK
    gen pea %1

from ext_addr to STACK
    gen pea {absolute4, %1.bd}

#if WORD_SIZE!=2
from consts to STACK
    gen pea {absolute4, %1.num}
#else
from sconsts4 to STACK
    gen pea {absolute4, %1.num}
from const4 to STACK
    gen pea {absolute4, %1.num}
#endif

from any4 to STACK
    gen move_l %1, {pre_dec4, sp}

#if WORD_SIZE!=2
from any2 to STACK
  uses DD_REG
    gen clr_l %a
	move_w %1, {dreg2, %a}
	move_l %a, {pre_dec4, sp}

from any2 to STACK
    gen clr_l {pre_dec4, sp}
	move_w %1, {offsetted2, sp, 2}
#else
from any2 to STACK
    gen move_w %1, {pre_dec2, sp}
#endif

from data1 to STACK
  uses DD_REG
#if WORD_SIZE!=2
    gen clr_l %a
	move_b %1, {dreg1, %a}
	move_l %a, {pre_dec4, sp}
#else
    gen clr_w %a
	move_b %1, {dreg1, %a}
	move_w %a, {pre_dec2, sp}
#endif

from data1 to STACK
#if WORD_SIZE!=2
    gen clr_l {pre_dec4, sp}
	move_b %1, {offsetted1, sp, 3}
#else
    gen clr_w {pre_dec2, sp}
	move_b %1, {offsetted1, sp, 1}
#endif

from extend2 to STACK
    gen ext_l	%1.reg
	move_l	%1.reg,{pre_dec4, sp}

from extend1_4 to STACK
#ifdef TBL68020
    gen extb_l	%1.reg
#else
    gen	ext_w	%1.reg
	ext_l	%1.reg
#endif
	move_l	%1.reg,{pre_dec4, sp}

#if WORD_SIZE==2
from extend1 to STACK
    gen ext_w %1.reg
	move_w %1.reg,{pre_dec2, sp}
#endif

#ifdef TBL68020
from regX to STACK
    gen pea %1
#endif /* TBL68020 */
	/* This last stackingrule is never used: whenever regX is put on
	 * the fakestack, some em-instuctions are left that remove it
	 * immediately. However cgg complained about not having a
	 * stackingrule for regX, so here it is
	 */

#if TBL68881
from FS_REG to STACK
    gen fmove_s %1,{pre_dec4,sp}

from FD_REG to STACK
    gen fmove_d %1,{pre_dec4,sp}
#endif
COERCIONS


from STACK
    uses DD_REG4
    gen move_l {post_inc4, sp}, %a
			yields	%a

#if WORD_SIZE==2
from STACK
    uses DD_REG
    gen move_w {post_inc2,sp}, %a
			yields %a
#endif

from STACK
    uses AA_REG
    gen move_l {post_inc4, sp}, %a
			yields	%a

#ifdef TBL68881
from STACK
    uses FS_REG
    gen fmove_s {post_inc4, sp}, %a
			yields	%a
from STACK
    uses FD_REG
    gen fmove_d {post_inc4, sp}, %a
			yields	%a
#endif

#ifndef TBL68020
from t_regAregXcon sfit(%bd, 8)
			yields	{regAregXcon, %1.reg, %1.xreg, 1, %1.bd}

from t_regAregXcon
    uses AA_REG=%1.reg
    gen add_l {const4, %1.bd}, %a
			yields	{regAregXcon, %a, %1.xreg, 1, 0}

/*
 * The following coercions are necessary because the code generator
 * must be able to make the token from the real stack, otherwise the
 * coercion will not be made.  Unfortunatly, inside a coercion, we are only
 * allowed to allocate 1 register, which means that there is no way to make
 * a regAregXcon from the stack, which, in its turn, means that the other
 * coercions will not be taken.
 *
/*from STACK
    uses AA_REG, DD_REG4 = {zero_const4, 0}
    gen move_l {post_inc4, sp}, %a
			yields	{regAregXcon, %a, %b, 1, 0}
*/
from STACK
    uses AA_REG
    gen move_l {post_inc4, sp}, %a
			yields	{regAcon, %a, 0}

from t_regAcon sfit(%bd, 16)
			yields	{regAcon, %1.reg, %1.bd}

from t_regAcon
    uses reusing %1, AA_REG=%1.reg
    gen add_l {const4, %1.bd}, %a
			yields	%a
#endif /* TBL68020 */

#if WORD_SIZE==2
from regAregXcon %bd==0 && %sc==1
    uses reusing %1, AA_REG = %1.reg
    gen add_l {dreg4,%1.xreg},%a
				yields %a

from regAregXcon %sc==1
    uses reusing %1, AA_REG = %1.reg
    gen add_l {dreg4, %1.xreg}, %a
				yields {regAcon, %a, %1.bd}
#endif

#if WORD_SIZE==2
from sconsts
    uses DD_REG4={const4, %1.num}			/* uses moveq */
				yields	%a.1
#endif

#if WORD_SIZE==2
from any2
uses reusing %1, DD_REG = %1	yields	%a
#endif

from any4
    uses reusing %1, DD_REG4 = %1
			yields	%a

from any4
    uses reusing %1, AA_REG = %1
			yields	%a

from t_address
    uses reusing %1, AA_REG = %1
			yields	%a

#if TBL68881
from data4
    uses reusing %1, FS_REG = %1
			yields	%a
#endif

from memory2
    uses DD_REG
#if WORD_SIZE!=2
		= {zero_const, 0}
#endif
    gen move_w %1, %a	yields	%a

from memory1
    uses DD_REG = {zero_const, 0}
    gen move_b %1, %a	yields	%a

from memory2
    uses DD_REG
    gen move_w %1, %a	yields	{dreg2, %a}

from memory1
    uses DD_REG
    gen move_b %1, %a	yields	{dreg1, %a}

from extend2
    gen ext_l	%1.reg	yields	%1.reg

#if WORD_SIZE==2
from extend1
    gen ext_w	%1.reg	yields %1.reg
#endif

from extend1_4
#ifdef TBL68020
    gen extb_l	%1.reg
#else
    gen	ext_w	%1.reg
	ext_l	%1.reg
#endif
			yields	%1.reg

PATTERNS

/********************************
 * First some longer patterns	*
 ********************************/

pat lol sbi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
with any_int
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen sub_i %1, {LOCAL, $1}
	neg_i {LOCAL, $1}

pat lol sbi stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
with conreg_int-bconst
    kills all_indir, LOCAL %bd==$1
    gen sub_i %1, {LOCAL, $1}
	neg_i {LOCAL, $1}

pat lol sbu stl $1==$3 && $2==WORD_SIZE
			leaving lol $1 sbi WORD_SIZE stl $1

pat lil sbi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
with conreg_int-bconst
    kills allexceptcon
    gen sub_i %1, {indirect_int, regvar($1, reg_pointer)}
	neg_i {indirect_int, regvar($1, reg_pointer)}

pat lil sbi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
with conreg_int-bconst
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}
    gen	sub_i %1, {indirect_int, %a}
	neg_i {indirect_int, %a}

pat lil sbu sil $1==$3 && $2==WORD_SIZE
			leaving lil $1 sbi WORD_SIZE sil $1

proc lolrbitstl example lol ngi stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen bit* {LOCAL, $1}

pat lol ngi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolrbitstl(NEG_I)
pat lol com stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolrbitstl(NOT_I)

proc lolbitstl example lol ngi stl
    kills all_indir, LOCAL %bd==$1
    gen bit* {LOCAL, $1}

pat lol ngi stl $1==$3 && $2==WORD_SIZE		call lolbitstl(NEG_I)
pat lol com stl $1==$3 && $2==WORD_SIZE		call lolbitstl(NOT_I)
#if WORD_SIZE==2
proc ldlbitsdl example ldl ngi sdl
    kills all_indir, DLOCAL %bd==$1
    gen bit* {DLOCAL, $1}

pat ldl ngi sdl $1==$3 && $2==4		call ldlbitsdl("neg.l")
pat ldl com sdl $1==$3 && $2==4		call ldlbitsdl("not.l")
#endif

proc loebitste example loe ngi ste
    kills posextern
    gen bit* {absolute_int, $1}

pat loe ngi ste $1==$3 && $2==WORD_SIZE		call loebitste(NEG_I)
pat loe com ste $1==$3 && $2==WORD_SIZE		call loebitste(NOT_I)
#if WORD_SIZE==2
proc ldebitsde example lde ngi sde
    kills posextern
    gen bit* {absolute4, $1}

pat lde ngi sde $1==$3 && $2==4		call ldebitsde("neg.l")
pat lde com sde $1==$3 && $2==4		call ldebitsde("not.l")
#endif

proc lilrbitsil example lil ngi sil
    kills allexceptcon
    gen bit* {indirect_int, regvar($1, reg_pointer)}

pat lil ngi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilrbitsil(NEG_I)
pat lil com sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilrbitsil(NOT_I)
pat lil dec sil $1==$3 && inreg($1)==reg_pointer
					call lilrbitsil(DEC)
pat lil inc sil $1==$3 && inreg($1)==reg_pointer
					call lilrbitsil(INC)

proc lilbitsil example lil ngi sil
    kills allexceptcon
#if TBL68020
    gen bit* {ILOCAL, $1}
#else
    uses AA_REG = {DLOCAL, $1}
    gen bit* {indirect_int, %a}
#endif

pat lil ngi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilbitsil(NEG_I)
pat lil com sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilbitsil(NOT_I)
pat lil dec sil $1==$3 && inreg($1)!=reg_any
					call lilbitsil(DEC)
pat lil inc sil $1==$3 && inreg($1)!=reg_any
					call lilbitsil(INC)

proc lolcshstl example lol loc sli stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen sh* {small_const, $2}, {LOCAL, $1}

pat lol loc sli stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(ASL_I)
pat lol loc sri stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(ASR_I)
pat lol loc slu stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(ASL_I)
pat lol loc sru stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(LSR_I)
pat lol loc rol stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(ROL_I)
pat lol loc ror stl $1==$4 && small($2) && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcshstl(ROR_I)

proc lolrshstl example lol lol sli stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen sh* {LOCAL, $2}, {LOCAL, $1}

pat lol lol sli stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
							&& inreg($2)==reg_any
					call lolrshstl(ASL_I)
pat lol lol slu stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
							&& inreg($2)==reg_any
					call lolrshstl(ASL_I)
pat lol lol sri stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
							&& inreg($2)==reg_any
					call lolrshstl(ASR_I)
pat lol lol sru stl $1==$4 && inreg($1)==reg_any && $3==WORD_SIZE
							&& inreg($2)==reg_any
					call lolrshstl(LSR_I)
pat lol lol rol stl $1==$4 && inreg($2)==reg_any && $3==WORD_SIZE
							&& inreg($1)==reg_any
					call lolrshstl(ROL_I)
pat lol lol ror stl $1==$4 && inreg($2)==reg_any && $3==WORD_SIZE
							&& inreg($1)==reg_any
					call lolrshstl(ROR_I)

#if WORD_SIZE!=2
proc lil1shlsil example lil loc sli sil		/* only left */
    kills allexceptcon
    gen shw* {offsetted2, regvar($1, reg_pointer), 2}
	roxl {indirect2, regvar($1, reg_pointer)}

pat lil loc sli sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lil1shlsil("asl #1,")
pat lil loc slu sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lil1shlsil("asl #1,")

proc lil1shrsil example lil loc sli sil		/* only right */
    kills allexceptcon
    gen shw* {indirect2, regvar($1, reg_pointer)}
	roxr {offsetted2, regvar($1, reg_pointer), 2}

pat lil loc sri sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lil1shrsil("asr #1,")
pat lil loc sru sil $1==$4 && $2==1 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lil1shrsil("lsr #1,")

#endif


pat LLP lof inc LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
    kills allexceptcon
    gen add_i {const, 1}, {offsetted_int, regvar($1, reg_pointer), $2}

pat LLP lof dec LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
    kills allexceptcon
    gen sub_i {const, 1}, {offsetted_int, regvar($1, reg_pointer), $2}

/* the patterns with adp should use add_l */
pat LLP LFP adp LLP SFP $1==$4 && $2==$5 && inreg($1)==reg_pointer
    kills allexceptcon
    gen add_l {const4, $3}, {offsetted4, regvar($1, reg_pointer), $2}

pat LEP LFP adp LEP SFP $1==$4 && $2==$5
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen add_l {const4, $3}, {ABS_off4, $1, $2}
#else
    uses AA_REG={absolute4, $1}
    gen add_l {const4, $3}, {offsetted4, %a, $2}
#endif

pat LEP loi adp LEP sti $1==$4 && $2==4 && $5==4
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen add_l {const4, $3}, {ABS_off4, $1, 0}
#else
    uses AA_REG={absolute4, $1}
    gen add_l {const4, $3}, {indirect4, %a}
#endif

#if WORD_SIZE!=2
pat lil lof adp lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen add_l {const4, $3}, {OFF_off4, regvar($1, reg_pointer), 0, $2}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen add_l {const4, $3}, {offsetted4, %a, $2}
#endif

pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen add_l {const4, $3}, {OFF_off4, regvar($1, reg_pointer), 0, 0}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen add_l {const4, $3}, {indirect4, %a}
#endif
#endif /* WORD_SIZE==2 */

pat lol inl $1==$2 && inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    uses DD_REG = {LOCAL, $1}
    gen add_i {const, 1}, {LOCAL, $1}
	killreg %a
			yields %a

pat lol del $1==$2 && inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    uses DD_REG = {LOCAL, $1}
    gen sub_i {const, 1}, {LOCAL, $1}
	killreg %a
			yields %a

/* the following rules are for unsigneds, since del and inl work on ints */
pat lol loc lol adu stl $1==$3 && $3==$5 && $4==WORD_SIZE && inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    uses DD_REG = {LOCAL, $1}
    gen add_i {const, $2}, {LOCAL, $1}
	killreg %a
			yields %a

pat lol loc lol adu stl $1==$3 && $3==$5 && $4==WORD_SIZE
    kills all_indir, LOCAL %bd==$1
    uses DD_REG = {LOCAL, $1}
    gen add_i {const, $2}, {LOCAL, $1}
    killreg %a
			yields %a

pat lol lol loc sbu stl $1==$2 && $2==$5 && $4==WORD_SIZE && inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    uses DD_REG = {LOCAL, $1}
    gen sub_i {const, $3}, {LOCAL, $1}
	killreg %a
			yields %a

pat lol lol loc sbu stl $1==$2 && $2==$5 && $4==WORD_SIZE
    kills all_indir, LOCAL %bd==$1
    uses DD_REG = {LOCAL, $1}
    gen sub_i {const, $3}, {LOCAL, $1}
	killreg %a
			yields %a

pat loe loc loe adu ste $1==$3 && $3==$5 && $4==WORD_SIZE
    kills posextern
    uses DD_REG = {absolute_int, $1}
    gen add_i {const,$2}, {absolute_int, $1}
    killreg %a
			yields	%a

pat loe loe loc sbu ste $1==$2 && $2==$5 && $4==WORD_SIZE
    kills posextern
    uses DD_REG = {absolute_int, $1}
    gen sub_i {const,$3}, {absolute_int, $1}
    killreg %a
			yields	%a

pat lil loc lil adu sil $1==$3 && $3==$5 && $4==WORD_SIZE
				&& inreg($1)==reg_pointer
    kills allexceptcon
    uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
    gen add_i {const, $2}, {indirect_int, regvar($1, reg_pointer)}
	killreg %a
			yields %a

pat lil lil loc sbu sil $1==$2 && $2==$5 && $4==WORD_SIZE
				&& inreg($1)==reg_pointer
    kills allexceptcon
    uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
    gen sub_i {const, $3}, {indirect_int, regvar($1, reg_pointer)}
	killreg %a
			yields %a

proc lolxxstl example lol and stl
with data_int-bconst
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen xxx* %1, {LOCAL, $1}

pat lol adi stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolxxstl(ADD_I)
pat lol adu stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolxxstl(ADD_I)
pat lol and stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolxxstl(AND_I)
pat lol ior stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
					call lolxxstl(OR_I)
pat lol xor stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
with conreg_int-bconst
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen eor_i %1, {LOCAL, $1}

#if TBL68020 || WORD_SIZE==2
pat lol mli stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
with data_int
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen muls_i %1, {LOCAL, $1}
pat lol mlu stl $1==$3 && $2==WORD_SIZE && inreg($1)==reg_any
with data_int
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen mulu_i %1, {LOCAL, $1}
#endif /* TBL68020 */

proc lolxxxstl example lol adi stl
with conreg_int-bconst
    kills all_indir, LOCAL %bd==$1
    gen xxx* %1, {LOCAL, $1}

pat lol adi stl $1==$3 && $2==WORD_SIZE		call lolxxxstl(ADD_I)
pat lol adu stl $1==$3 && $2==WORD_SIZE		call lolxxxstl(ADD_I)
pat lol and stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
					call lolxxxstl(AND_I)
pat lol ior stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
					call lolxxxstl(OR_I)
pat lol xor stl $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_pointer
					call lolxxxstl(EOR_I)

#if WORD_SIZE==2
proc ldlxxxsdl example lol adi stl
with conreg4-bconst4
    kills all_indir, DLOCAL %bd==$1
    gen xxx* %1, {DLOCAL, $1}

pat ldl adi sdl $1==$3 && $2==4		call ldlxxxsdl("add.l")
pat ldl adu sdl $1==$3 && $2==4		call ldlxxxsdl("add.l")
pat ldl and sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
					call ldlxxxsdl("and.l")
pat ldl ior sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
					call ldlxxxsdl("or.l")
pat ldl xor sdl $1==$3 && $2==4 && inreg($1)!=reg_pointer
					call ldlxxxsdl("eor.l")
#endif

proc lilxxsil example lil and sil
with conreg_int-bconst
    kills allexceptcon
    gen xxx* %1, {indirect_int, regvar($1, reg_pointer)}

pat lil adi sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilxxsil(ADD_I)
pat lil adu sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilxxsil(ADD_I)
pat lil and sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilxxsil(AND_I)
pat lil ior sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilxxsil(OR_I)
pat lil xor sil $1==$3 && $2==WORD_SIZE && inreg($1)==reg_pointer
					call lilxxsil(EOR_I)
#if WORD_SIZE!=2
pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_pointer
					 call lilxxsil("add.l")
#endif

proc lilxxxsil example lil adi sil
with conreg_int-bconst
    kills allexceptcon
#if TBL68020
    gen xxx* %1, {ILOCAL, $1}
#else
    uses AA_REG = {DLOCAL, $1}
    gen xxx* %1, {indirect_int, %a}
#endif

pat lil adi sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilxxxsil(ADD_I)
pat lil adu sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilxxxsil(ADD_I)
pat lil and sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilxxxsil(AND_I)
pat lil ior sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilxxxsil(OR_I)
pat lil xor sil $1==$3 && $2==WORD_SIZE && inreg($1)!=reg_any
					call lilxxxsil(EOR_I)
#if WORD_SIZE!=2
pat lil ads sil $1==$3 && $2==4 && inreg($1)!=reg_any
					call lilxxxsil("add.l")
#endif

proc loexxxste example loe adi ste
with conreg_int-bconst
    kills posextern
    gen xxx* %1, {absolute_int, $1}

pat loe adi ste $1==$3 && $2==WORD_SIZE		call loexxxste(ADD_I)
pat loe adu ste $1==$3 && $2==WORD_SIZE		call loexxxste(ADD_I)
pat loe and ste $1==$3 && $2==WORD_SIZE		call loexxxste(AND_I)
pat loe ior ste $1==$3 && $2==WORD_SIZE		call loexxxste(OR_I)
pat loe xor ste $1==$3 && $2==WORD_SIZE		call loexxxste(EOR_I)
#if WORD_SIZE!=2
pat loe ads ste $1==$3 && $2==4			call loexxxste("add.l")
#endif

#if WORD_SIZE==2
proc ldexxxsde example lde adi sde
with conreg4-bconst4
    kills posextern
    gen xxx* %1, {absolute4, $1}

pat lde adi sde $1==$3 && $2==4			call ldexxxsde("add.l")
pat lde adu sde $1==$3 && $2==4			call ldexxxsde("add.l")
pat lde and sde $1==$3 && $2==4			call ldexxxsde("and.l")
pat lde ior sde $1==$3 && $2==4			call ldexxxsde("or.l")
pat lde xor sde $1==$3 && $2==4			call ldexxxsde("eor.l")
#endif

proc lollilxxxstl example lol lil adi stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen xxx* {indirect_int, regvar($2, reg_pointer)}, {LOCAL, $1}

pat lol lil adi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(ADD_I)
pat lol lil adu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(ADD_I)
pat lol lil sbi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(SUB_I)
pat lol lil sbu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(SUB_I)
pat lol lil and stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(AND_I)
pat lol lil ior stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					    && inreg($2)==reg_pointer
					call lollilxxxstl(OR_I)

proc lollfixxxstl example lol LLP lof adi stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen xxx* {offsetted_int, regvar($2, reg_pointer), $3}, {LOCAL, $1}

pat lol LLP lof adi stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(ADD_I)
pat lol LLP lof adu stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(ADD_I)
pat lol LLP lof sbi stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(SUB_I)
pat lol LLP lof sbu stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(SUB_I)
pat lol LLP lof and stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(AND_I)
pat lol LLP lof ior stl $1==$5 && $4==WORD_SIZE && inreg($1)==reg_any
						&& inreg($2)==reg_pointer
					call lollfixxxstl(OR_I)


proc lolfrxlolf example LLP lof and LLP stf
with conreg_int-bconst
    kills allexceptcon
    gen xxx* %1, {offsetted_int, regvar($1, reg_pointer), $2}

pat LLP lof adi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
						    && inreg($1)==reg_pointer
					call lolfrxlolf(ADD_I)
pat LLP lof adu LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
						    && inreg($1)==reg_pointer
					call lolfrxlolf(ADD_I)
pat LLP lof and LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
						    && inreg($1)==reg_pointer
					call lolfrxlolf(AND_I)
pat LLP lof ior LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
						    && inreg($1)==reg_pointer
					call lolfrxlolf(OR_I)
pat LLP lof xor LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
						    && inreg($1)==reg_pointer
					call lolfrxlolf(EOR_I)
#if WORD_SIZE!=2
pat LLP lof ads LLP stf $1==$4 && $2==$5 && $3==4
						    && inreg($1)==reg_pointer
					call lolfrxlolf("add.l")
#endif

proc lolfxxlolf example LLP lof and LLP stf
with conreg_int-bconst
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen xxx* %1, {OFF_off_int, lb, $1, $2}
#else
    uses AA_REG={DLOCAL, $1}
    gen xxx* %1, {offsetted_int, %a, $2}
#endif

pat LLP lof adi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lolfxxlolf(ADD_I)
pat LLP lof adu LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lolfxxlolf(ADD_I)
pat LLP lof and LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lolfxxlolf(AND_I)
pat LLP lof ior LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lolfxxlolf(OR_I)
pat LLP lof xor LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lolfxxlolf(EOR_I)
#if WORD_SIZE!=2
pat LLP lof ads LLP stf $1==$4 && $2==$5 && $3==4
					call lolfxxlolf("add.l")
#endif

#if WORD_SIZE!=2
proc lilfxxlilf example lil lof and lil stf
with conreg_int-bconst
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen xxx* %1, {OFF_off4, regvar($1, reg_pointer), 0, $2}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen xxx* %1, {offsetted_int, %a, $2}
#endif

pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("add.l")
pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("add.l")
pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("and.l")
pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("or.l")
pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("eor.l")
pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lilfxxlilf("add.l")
#endif

proc lefxxxsef example loe lof and loe stf
with conreg_int-bconst
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen xxx* %1, {ABS_off_int, $1, $2}
#else
    uses AA_REG={absolute4, $1}
    gen xxx* %1, {offsetted_int, %a, $2}
#endif

pat LEP lof adi LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lefxxxsef(ADD_I)
pat LEP lof adu LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lefxxxsef(ADD_I)
pat LEP lof and LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lefxxxsef(AND_I)
pat LEP lof ior LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lefxxxsef(OR_I)
pat LEP lof xor LEP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lefxxxsef(EOR_I)
#if WORD_SIZE!=2
pat LEP lof ads LEP stf $1==$4 && $2==$5 && $3==4
					call lefxxxsef("add.l")
#endif

/* lil gets a word, not necessarily a pointer */
#if WORD_SIZE!=2
proc lilixxlili example lil loi and lil sti
with conreg_int-bconst
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen xxx* %1, {OFF_off4, regvar($1, reg_pointer), 0, 0}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen xxx* %1, {indirect4, %a}
#endif

pat lil loi adi lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
						    && inreg($1)==reg_pointer
					call lilixxlili("add.l")
pat lil loi adu lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
						    && inreg($1)==reg_pointer
					call lilixxlili("add.l")
pat lil loi and lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
						    && inreg($1)==reg_pointer
					call lilixxlili("and.l")
pat lil loi ior lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
						    && inreg($1)==reg_pointer
					call lilixxlili("or.l")
pat lil loi xor lil sti $1==$4 && $2==$3 && $2==$5 && $2==4
						    && inreg($1)==reg_pointer
					call lilixxlili("eor.l")
pat lil loi ads lil sti $1==$4 && $2==$3 && $2==$5 && $3==4
						    && inreg($1)==reg_pointer
					call lilixxlili("add.l")
#endif

proc leixxxsei example loe loi and loe sti
with conreg_int-bconst
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen xxx* %1, {ABS_off_int, $1, 0}
#else
    uses AA_REG={absolute4, $1}
    gen xxx* %1, {indirect_int, %a}
#endif

pat LEP loi adi LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leixxxsei(ADD_I)
pat LEP loi adu LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leixxxsei(ADD_I)
pat LEP loi and LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leixxxsei(AND_I)
pat LEP loi ior LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leixxxsei(OR_I)
pat LEP loi xor LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leixxxsei(EOR_I)
#if WORD_SIZE!=2
pat LEP loi ads LEP sti $1==$4 && $2==$3 && $2==$5 && $2==4
					call leixxxsei("add.l")
#endif

proc lofruxxsof example LLP lof inc LLP stf
    kills allexceptcon
    gen bit* {offsetted_int, regvar($1, reg_pointer), $2}

pat LLP lof inc LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
					call lofruxxsof(INC)
pat LLP lof dec LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
					call lofruxxsof(DEC)
pat LLP lof ngi LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
							&& $3==WORD_SIZE
					call lofruxxsof(NEG_I)
pat LLP lof com LLP stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
							&& $3==WORD_SIZE
					call lofruxxsof(NOT_I)

proc lofuxxsof example LLP lof inc LLP stf
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen bit* {OFF_off_int, lb, $1, $2}
#else
    uses AA_REG={DLOCAL,$1}
    gen bit* {offsetted_int,%a,$2}
#endif

pat LLP lof inc LLP stf $1==$4 && $2==$5
					call lofuxxsof(INC)
pat LLP lof dec LLP stf $1==$4 && $2==$5
					call lofuxxsof(DEC)
pat LLP lof ngi LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lofuxxsof(NEG_I)
pat LLP lof com LLP stf $1==$4 && $2==$5 && $3==WORD_SIZE
					call lofuxxsof(NOT_I)

#if WORD_SIZE!=2
proc lifuxxsif example lil lof inc lil stf
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen bit* {OFF_off4, regvar($1, reg_pointer), 0, $2}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen bit* {offsetted4,%a,$2}
#endif

pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
					call lifuxxsif("add.l #1,")
pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)==reg_pointer
					call lifuxxsif("sub.l #1,")
pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lifuxxsif("neg.l")
pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_pointer
					call lifuxxsif("not.l")
#endif

#if WORD_SIZE!=2
proc liiuxxsii example lil loi inc lil sti
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen bit* {OFF_off4, regvar($1, reg_pointer), 0, 0}
#else
    uses AA_REG={indirect4, regvar($1, reg_pointer)}
    gen bit* {indirect4, %a}
#endif

pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
					call liiuxxsii("add.l #1,")
pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)==reg_pointer
					call liiuxxsii("sub.l #1,")
pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)==reg_pointer
					call liiuxxsii("neg.l")
pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)==reg_pointer
					call liiuxxsii("not.l")
#endif

proc lefuxxsef example loe lof inc loe stf
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen bit* {ABS_off_int, $1, $2}
#else
    uses AA_REG={absolute4, $1}
    gen bit* {offsetted_int, %a, $2}
#endif

pat LEP lof inc LEP stf $1==$4 && $2==$5
					call lefuxxsef(INC)
pat LEP lof dec LEP stf $1==$4 && $2==$5
					call lefuxxsef(DEC)
pat LEP lof ngi LEP stf $1==$4 && $2==$5 && $3==4
					call lefuxxsef(NEG_I)
pat LEP lof com LEP stf $1==$4 && $2==$5 && $3==4
					call lefuxxsef(NOT_I)

proc leiuxxsei example loe loi inc loe sti
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen bit* {ABS_off_int, $1, 0}
#else
    uses AA_REG={absolute4, $1}
    gen bit* {indirect_int, %a}
#endif

pat LEP loi inc LEP sti $1==$4 && $2==$5 && $2==WORD_SIZE
					call leiuxxsei(INC)
pat LEP loi dec LEP sti $1==$4 && $2==$5 && $2==WORD_SIZE
					call leiuxxsei(DEC)
pat LEP loi ngi LEP sti $1==$4 && $2==$3 && $2==$5 && $2==WORD_SIZE
					call leiuxxsei(NEG_I)
pat LEP loi com LEP sti $1==$4 && $2==$3 && 2==$5 && $2==WORD_SIZE
					call leiuxxsei(NOT_I)

proc lolcxxstl example lol loc and stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen xxx* {const, $2}, {LOCAL, $1}

/*
pat lol loc adi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(ADD_I)
pat lol loc adu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(ADD_I)
	peephole optimizer replaces these
*/
pat lol loc sbi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(SUB_I)
pat lol loc sbu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(SUB_I)
/*
pat lol loc and stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(AND_I)
pat lol loc ior stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(OR_I)
pat lol loc xor stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(EOR_I)
	peephole optimizer replaces these
*/
#if TBL68020 || WORDSIZE==2
#if WORD_SIZE==4
pat lol loc dvi stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(DIVS_I)
pat lol loc dvu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(DIVU_I)
#endif
pat lol loc mli stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(MULS_I)
pat lol loc mlu stl $1==$4 && $3==WORD_SIZE && inreg($1)==reg_any
					call lolcxxstl(MULU_I)
#endif

proc lolcxxxstl example lol loc adi stl
    kills all_indir, LOCAL %bd==$1
    gen xxx* {const, $2}, {LOCAL, $1}

/*
pat lol loc adi stl $1==$4 && $3==WORD_SIZE	call lolcxxxstl(ADD_I)
pat lol loc adu stl $1==$4 && $3==WORD_SIZE	call lolcxxxstl(ADD_I)
	peephole optimizer replaces these
*/
pat lol loc sbi stl $1==$4 && $3==WORD_SIZE	call lolcxxxstl(SUB_I)
pat lol loc sbu stl $1==$4 && $3==WORD_SIZE	call lolcxxxstl(SUB_I)
/*
pat lol loc and stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
					call lolcxxxstl(AND_I)
pat lol loc ior stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
					call lolcxxxstl(OR_I)
pat lol loc xor stl $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_pointer
					call lolcxxxstl(EOR_I)
	peephole optimizer replaces these
*/
#if WORD_SIZE==2
proc ldlcxxxsdl example ldl ldc adi sdl
    kills all_indir, DLOCAL %bd==$1
    gen xxx* {const4, $2}, {DLOCAL, $1}

pat ldl ldc sbi sdl $1==$4 && $3==4		call ldlcxxxsdl("sub.l")
pat ldl ldc sbu sdl $1==$4 && $3==4		call ldlcxxxsdl("sub.l")
#endif

proc lilcxxsil example lil loc and sil
    kills allexceptcon
    gen xxx* {const, $2}, {indirect_int, regvar($1, reg_pointer)}

pat lil loc adi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(ADD_I)
pat lil loc adu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(ADD_I)
pat lil loc sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(SUB_I)
pat lil loc sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(SUB_I)
pat lil loc and sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(AND_I)
pat lil loc ior sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(OR_I)
pat lil loc xor sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
					call lilcxxsil(EOR_I)

proc lilcxxxsil example lil loc adi sil
    kills allexceptcon
#if TBL68020
    gen xxx* {const, $2}, {ILOCAL, $1}
#else
    uses AA_REG = {DLOCAL, $1}
    gen xxx* {const, $2}, {indirect_int, %a}
#endif

pat lil loc adi sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(ADD_I)
pat lil loc adu sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(ADD_I)
pat lil loc sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(SUB_I)
pat lil loc sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(SUB_I)
pat lil loc and sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(AND_I)
pat lil loc ior sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(OR_I)
pat lil loc xor sil $1==$4 && $3==WORD_SIZE && inreg($1)!=reg_any
					call lilcxxxsil(EOR_I)

proc loecxxxste example loe loc adi ste
    kills posextern
    gen xxx* {const, $2}, {absolute4, $1}

/*
pat loe loc adi ste $1==$4 && $3==WORD_SIZE	call loecxxxste(ADD_I)
pat loe loc adu ste $1==$4 && $3==WORD_SIZE	call loecxxxste(ADD_I)
	peephole optimizer replaces these
*/
pat loe loc sbi ste $1==$4 && $3==WORD_SIZE	call loecxxxste(SUB_I)
pat loe loc sbu ste $1==$4 && $3==WORD_SIZE	call loecxxxste(SUB_I)
/*
pat loe loc and ste $1==$4 && $3==WORD_SIZE	call loecxxxste(AND_I)
pat loe loc ior ste $1==$4 && $3==WORD_SIZE	call loecxxxste(OR_I)
pat loe loc xor ste $1==$4 && $3==WORD_SIZE	call loecxxxste(EOR_I)
	peephole optimizer replaces these
*/

proc lolrxxstl example lol lol and stl
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen xxx* {LOCAL, $2}, {LOCAL, $1}

/*
pat lol lol adi stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(ADD_I)
pat lol lol adu stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(ADD_I)
	peephole optimizer replaces these
*/
pat lol lol sbi stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(SUB_I)
pat lol lol sbu stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(SUB_I)
/*
pat lol lol and stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(AND_I)
pat lol lol ior stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(OR_I)
pat lol lol xor stl $1==$4 && $3==WORD_SIZE
				&& inreg($1)==reg_any && inreg($2)==reg_any
					call lolrxxstl(EOR_I)
	peephole optimizer replaces these
*/

proc lolrxxxstl example lol lol adi stl
    kills all_indir, LOCAL %bd==$1
    gen xxx* {LOCAL, $2}, {LOCAL, $1}

/*
pat lol lol adi stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call lolrxxxstl(ADD_I)
pat lol lol adu stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call lolrxxxstl(ADD_I)
	peephole optimizer replaces these
*/
#if WORD_SIZE!=2
pat lol lol ads stl $1==$4 && $3==4 && inreg($2)==reg_any
					call lolrxxxstl("add.l")
#endif
pat lol lol sbi stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call lolrxxxstl(SUB_I)
pat lol lol sbu stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call lolrxxxstl(SUB_I)
/*
pat lol lol and stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any && inreg($1)!=reg_pointer
					call lolrxxxstl(AND_I)
pat lol lol ior stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any &&
			inreg($1)!=reg_pointer
					call lolrxxxstl(OR_I)
pat lol lol xor stl $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any &&
			inreg($1)!=reg_pointer
					call lolrxxxstl(EOR_I)
	peephole optimizer replaces these
*/

proc lilrxxsil example lil lol and sil
    kills allexceptcon
    gen xxx* {LOCAL, $2}, {indirect_int, regvar($1, reg_pointer)}

pat lil lol adi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(ADD_I)
pat lil lol adu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(ADD_I)
pat lil lol sbi sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(SUB_I)
pat lil lol sbu sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(SUB_I)
pat lil lol and sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(AND_I)
pat lil lol ior sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(OR_I)
pat lil lol xor sil $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil(EOR_I)
#if WORD_SIZE!=2
pat lil lol ads sil $1==$4 && $3==4 && inreg($1)==reg_pointer &&
						inreg($2)==reg_any
					call lilrxxsil("add.l")
#endif

proc lilrxxxsil example lil lol adi sil
    kills allexceptcon
#if TBL68020
    gen xxx* {LOCAL, $2}, {ILOCAL, $1}
#else
    uses AA_REG = {DLOCAL, $1}
    gen xxx* {LOCAL, $2}, {indirect_int, %a}
#endif

pat lil lol adi sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(ADD_I)
pat lil lol adu sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(ADD_I)
pat lil lol sbi sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(SUB_I)
pat lil lol sbu sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(SUB_I)
pat lil lol and sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(AND_I)
pat lil lol ior sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(OR_I)
pat lil lol xor sil $1==$4 && $3==WORD_SIZE
				    && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil(EOR_I)
#if WORD_SIZE!=2
pat lil lol ads sil $1==$4 && $3==4 && inreg($2)==reg_any && inreg($1)!=reg_any
					call lilrxxxsil("add.l")
#endif

proc loerxxxste example loe lol adi ste
    kills posextern
    gen xxx* {LOCAL, $2}, {absolute_int, $1}

pat loe lol adi ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(ADD_I)
pat loe lol adu ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(ADD_I)
pat loe lol sbi ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(SUB_I)
pat loe lol sbu ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(SUB_I)
pat loe lol and ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(AND_I)
pat loe lol ior ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(OR_I)
pat loe lol xor ste $1==$4 && $3==WORD_SIZE && inreg($2)==reg_any
					call loerxxxste(EOR_I)
#if WORD_SIZE!=2
pat loe lol ads ste $1==$4 && $3==4 && inreg($2)==reg_any
					call loerxxxste("add.l")
#endif

proc xxxstl example adi stl
with any_int-RD_REG-dreg_int any-RD_REG-dreg_int
    kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
    gen	move %2,{dreg_int, regvar($2)}
	xxx* %1,{LOCAL,$2}
with exact any_int-RD_REG-dreg_int STACK
    kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
    gen move_i {post_inc_int, sp}, {dreg_int, regvar($2)}
	xxx* %1,{LOCAL,$2}

pat adi stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(ADD_I)
pat adu stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(ADD_I)
pat sbi stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(SUB_I)
pat sbu stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(SUB_I)
pat and stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(AND_I)
pat ior stl $1==WORD_SIZE && inreg($2)==reg_any	call xxxstl(OR_I)

pat xor stl $1==WORD_SIZE && inreg($2)==reg_any
with D_REG any_int
    kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
    gen	move %2,{dreg_int, regvar($2)}
	eor_i %1,{dreg_int, regvar($2)}

pat ads SLP $1==4 && inreg($2)==reg_pointer
with any4-areg-RA_REG any4+address-areg-RA_REG
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move %2,{areg,regvar($2,reg_pointer)}
	add_l %1,{areg,regvar($2,reg_pointer)}
#ifdef TBL68020
with regX any4+address-areg-RA_REG
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move %2,{areg,regvar($2,reg_pointer)}
	move {regAregXcon, regvar($2,reg_pointer), %1.xreg, %1.sc, 0},{areg,regvar($2,reg_pointer)}
with exact regX STACK
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_l {post_inc4, sp},{areg,regvar($2,reg_pointer)}
	move {regAregXcon, regvar($2,reg_pointer), %1.xreg, %1.sc, 0},{areg,regvar($2,reg_pointer)}
with exact regX regAcon	
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move {regAregXcon, %2.reg, %1.xreg, %1.sc, %2.bd},{areg,regvar($2,reg_pointer)}
with exact regX local_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {regAregXcon, lb, %1.xreg, %1.sc, %2.bd},{areg,regvar($2,reg_pointer)}
#ifdef FANCY_MODES
with exact regX indirect4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, %2.reg, %1.xreg,%1.sc,0,0},{areg,regvar($2,reg_pointer)}
with exact regX offsetted4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, %2.reg, %1.xreg, %1.sc, %2.bd, 0},{areg,regvar($2,reg_pointer)}
with exact regX LOCAL
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, lb, %1.xreg, %1.sc, %2.bd, 0},{areg,regvar($2,reg_pointer)}
with exact regX off_con
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, %2.reg, %1.xreg,%1.sc,%2.bd,%2.od},{areg,regvar($2,reg_pointer)}
with exact regX ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move{ext_regX, %1.sc, %1.xreg, %2.bd},{areg,regvar($2,reg_pointer)}
with exact regX absolute4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {abs_regXcon, %1.sc, %1.xreg, %2.bd, 0},{areg,regvar($2,reg_pointer)}
with exact regX abs_con
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {abs_regXcon, %1.sc, %1.xreg, %2.bd, %2.od},{areg,regvar($2,reg_pointer)}
with exact indirect4 ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_con, %1.reg, 0, %2.bd},{areg,regvar($2,reg_pointer)}
with exact offsetted4 ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_con, %1.reg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
with exact LOCAL ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_con, lb, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
with exact index_off4 ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {indoff_con, %1.reg, %1.xreg, %1.sc,%1.bd,%2.bd},{areg,regvar($2,reg_pointer)}
with exact absolute4 ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {abs_con, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
with exact abs_index4 ext_addr
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {absind_con, %1.sc, %1.xreg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
with exact indirect4 ext_regX
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, %1.reg, %2.xreg, %2.sc, 0, %2.bd},{areg,regvar($2,reg_pointer)}
with exact offsetted4 ext_regX
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, %1.reg, %2.xreg,%2.sc,%1.bd,%2.bd},{areg,regvar($2,reg_pointer)}
with exact LOCAL ext_regX
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {off_regXcon, lb, %2.xreg, %2.sc, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
with exact absolute4 ext_regX
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move {abs_regXcon, %2.sc, %2.xreg, %1.bd, %2.bd},{areg,regvar($2,reg_pointer)}
#endif	/* FANCY_MODES */
#endif	/* TBL68020 */


proc xxxdupstl example adi dup stl
with any_int-RD_REG-dreg_int any-RD_REG-dreg_int
    kills regvar($3, reg_any), use_index %xreg==regvar($3, reg_any)
    gen	move %2,{dreg_int, regvar($3)}
	xxx* %1,{LOCAL,$3}		yields {LOCAL, $3}
with exact any_int-RD_REG-dreg_int STACK
    kills regvar($3, reg_any), use_index %xreg==regvar($3, reg_any)
    gen move_i {post_inc_int, sp}, {dreg_int, regvar($3)}
	xxx* %1,{LOCAL,$3}		yields {LOCAL, $3}

pat adi dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(ADD_I)
pat adu dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(ADD_I)
pat sbi dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(SUB_I)
pat sbu dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(SUB_I)
pat and dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(AND_I)
pat ior dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(OR_I)
/*
pat xor dup stl $1==$2 && $2==WORD_SIZE && inreg($3)==reg_any
					    call xxxdupstl(EOR_I)
	incorrect for eor.l !!!
*/

pat dup stl $1==WORD_SIZE && inreg($2)==reg_any
with any_int
    kills regvar($2, reg_any), use_index %xreg==regvar($2, reg_any)
    gen move %1,{dreg_int, regvar($2,reg_any)}
					yields {LOCAL, $2}

pat dup stl $1==4 && inreg($2)==reg_pointer
with any4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move_l %1,{areg, regvar($2, reg_pointer)}
					yields {DLOCAL, $2}

pat dup LLP sti LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==1 && $5==1
    with any1
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_b %1,{post_inc1, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup LLP sti LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==1 && $5==1
    with any1
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_b %1,{post_inc1, regvar($2,reg_pointer)}
	beq {llabel, $7}

/* Normally, LLP sti wth word size will be optimized to sil */
pat dup LLP sti LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==2 && $5==2
    with any2
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_w %1,{post_inc2, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup LLP sti LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==2 && $5==2
    with any2
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_w %1,{post_inc2, regvar($2,reg_pointer)}
	beq {llabel, $7}

#if WORD_SIZE!=2
/* m68k2 can't do zne/zeq on 4-byte */
pat dup LLP sti LLP adp SLP zne $1==4 && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==4 && $5==4
    with any4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_l %1,{post_inc4, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup LLP sti LLP adp SLP zeq $1==4 && inreg($2)==reg_pointer &&
				$2==$4 && $2==$6 && $3==4 && $5==4
    with any4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_l %1,{post_inc4, regvar($2,reg_pointer)}
	beq {llabel, $7}
#endif

pat dup sil LLP adp SLP zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$3 && $3==$5 && $4==WORD_SIZE
    with any_int
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move_i %1,{post_inc_int, regvar($2, reg_pointer)}
	bne {llabel, $6}

pat dup sil LLP adp SLP zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$3 && $3==$5 && $4==WORD_SIZE
    with any_int
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen move_i %1,{post_inc_int, regvar($2, reg_pointer)}
	beq {llabel, $6}

pat sil lil LLP adp SLP zne $1==$2 && $2==$3 && $3==$5 && $4==WORD_SIZE
				&& inreg($1)==reg_pointer
    with any_int
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move_i %1,{post_inc_int, regvar($1,reg_pointer)}
	bne {llabel, $6}

pat sil lil LLP adp SLP zeq $1==$2 && $2==$3 && $3==$5 && $4==WORD_SIZE
				&& inreg($1)==reg_pointer
    with any_int
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move_i %1,{post_inc_int, regvar($1,reg_pointer)}
	beq {llabel, $6}

pat dup LLP adp SLP LLP sti zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==1 && $4==(0-1)
    with any1
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_b %1,{pre_dec1, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup LLP adp SLP LLP sti zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==1 && $4==(0-1)
    with any1
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_b %1,{pre_dec1, regvar($2,reg_pointer)}
	beq {llabel, $7}

#if WORD_SIZE!=2
pat dup LLP adp SLP LLP sti zne $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==2 && $4==(0-2)
    with any2
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_w %1,{pre_dec2, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup LLP adp SLP LLP sti zeq $1==WORD_SIZE && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==2 && $4==(0-2)
    with any2
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_w %1,{pre_dec2, regvar($2,reg_pointer)}
	beq {llabel, $7}
#endif

#if WORD_SIZE!=2
pat dup lol adp stl lol sti zne $1==4 && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==4 && $4==(0-4)
    with any4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_l %1,{pre_dec4, regvar($2,reg_pointer)}
	bne {llabel, $7}

pat dup lol adp stl lol sti zeq $1==4 && inreg($2)==reg_pointer &&
				$2==$4 && $4==$5 && $6==4 && $4==(0-4)
    with any4
    kills regvar($2, reg_pointer), all_regind %reg==regvar($2, reg_pointer)
    gen	move_l %1,{pre_dec4, regvar($2,reg_pointer)}
	beq {llabel, $7}
#endif

pat LLP ads SLP $1==$3 && $2==4 && inreg($1)==reg_pointer
    with data4-sconsts
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen add_l %1, {DLOCAL, $1}

pat lil lil inc sil $1==$2 && $1==$4 && inreg($1)==reg_pointer
    kills allexceptcon
    uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
    gen add_i {const, 1}, {indirect_int, regvar($1, reg_pointer)}
    killreg %a
			yields	%a

pat lil lil dec sil $1==$2 && $1==$4 && inreg($1)==reg_pointer
    kills allexceptcon
    uses DD_REG = {indirect_int, regvar($1, reg_pointer)}
    gen sub_i {const, 1}, {indirect_int, regvar($1, reg_pointer)}
    killreg %a
			yields	%a

pat LLP LFP dup adp LLP SFP sti $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {offsetted4, regvar($1, reg_pointer), $2}
    gen add_l {const4, $4}, {offsetted4, regvar($1, reg_pointer), $2}
    killreg %a
			yields	%1 %a		leaving sti $7

pat LLP LFP dup adp LLP SFP $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer
    kills allexceptcon
    uses AA_REG = {offsetted4, regvar($1, reg_pointer), $2}
    gen add_l {const4, $4}, {offsetted4, regvar($1, reg_pointer), $2}
    killreg %a
			yields	%a

pat LLP LFP dup adp LLP SFP sti $3==4 && $1==$5 && $2==$6 && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%1 %b		leaving sti $7

pat LLP LFP dup adp LLP SFP $3==4 && $1==$5 && $2==$6
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%b

pat LEP LFP dup adp LEP SFP sti $3==4 && $1==$5 && $2==$6 && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {absolute4, $1}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%1 %b		leaving sti $7

pat LEP LFP dup adp LEP SFP $3==4 && $1==$5 && $2==$6
    kills allexceptcon
    uses AA_REG = {absolute4, $1}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%b

#if WORD_SIZE!=2
pat lil lof dup adp lil stf sti $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%1 %b		leaving sti $7

pat lil lof dup adp lil stf $3==4 && $1==$5 && $2==$6 && inreg($1)==reg_pointer
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
    gen move_l {offsetted4, %a, $2}, %b
	add_l {const4, $4}, {offsetted4, %a, $2}
			yields	%b
#endif	/* WORD_SIZE==2 */

pat LEP loi dup adp LEP sti sti $3==4 && $1==$5 && $2==4 && $6==4 && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {absolute4, $1}, AA_REG
    gen move_l {indirect4, %a}, %b
	add_l {const4, $4}, {indirect4, %a}
			yields	%1 %b		leaving sti $7

pat LEP loi dup adp LEP sti $3==4 && $1==$5 && $2==4 && $6==4
    kills allexceptcon
    uses AA_REG = {absolute4, $1}, AA_REG
    gen move_l {indirect4, %a}, %b
	add_l {const4, $4}, {indirect4, %a}
			yields	%b

#if WORD_SIZE!=2
pat lil loi dup adp lil sti sti $3==4 && $1==$5 && $2==4 && $6==4 && $7 <= 4
    with conreg
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
    gen move_l {indirect4, %a}, %b
	add_l {const4, $4}, {indirect4, %a}
			yields	%1 %b		leaving sti $7

pat lil loi dup adp lil sti $3==4 && $1==$5 && $2==4 && $6==4
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}, AA_REG
    gen move_l {indirect4, %a}, %b
	add_l {const4, $4}, {indirect4, %a}
			yields	%b
#endif

pat LLP LLP adp SLP lae cmp $1==$2 && $2==$4 && inreg($1)==reg_pointer && $3 < 0
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen	sub_l {const4,0-$3},{DLOCAL,$1}
			yields {DLOCAL,$1} {ext_addr, $5+$3}
					leaving cmu 4

pat LLP LLP adp SLP lae cmp $1==$2 && $2==$4 && inreg($1)==reg_pointer && $3 > 0
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen	add_l {const4,$3},{DLOCAL,$1}
			yields {DLOCAL,$1} {ext_addr, $5+$3}
					leaving cmu 4

pat LLP LLP adp SLP loi $1==$2 && $1==$4 && $3==4 && $5==4 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{post_inc4, regvar($1, reg_pointer)}

pat LLP LLP adp SLP loi $1==$2 && $1==$4 && $3==$5 && inreg($1)==reg_pointer
				leaving LLP $1 loi $5 LLP $2 adp $3 SLP $4

pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==1 && $4==1 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{post_inc1, regvar($1, reg_pointer)}

/* Normally, LLP loi will be optimized to lil */
pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==2 && $4==2 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{post_inc2, regvar($1, reg_pointer)}

pat LLP loi LLP adp SLP $1==$3 && $1==$5 && $2==4 && $4==4 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{post_inc4, regvar($1, reg_pointer)}

pat lil LLP adp SLP $1==$2 && $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{post_inc_int, regvar($1, reg_pointer)}

pat LLP LLP adp SLP sti $1==$2 && $1==$4 && $3==$5 && inreg($1)==reg_pointer
				leaving LLP $1 sti $5 LLP $2 adp $3 SLP $4

pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==1 && $4==1 &&
						inreg($1)==reg_pointer
with any1
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {post_inc1, regvar($1, reg_pointer)}

/* Normally, LLP sti will ve optimzed into sil */
pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==2 && $4==2 &&
						inreg($1)==reg_pointer
with any2
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {post_inc2, regvar($1, reg_pointer)}

pat LLP sti LLP adp SLP $1==$3 && $1==$5 && $2==4 && $4==4 &&
						inreg($1)==reg_pointer
with any4
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {post_inc4, regvar($1, reg_pointer)}

pat LLP LLP adp SLP sti $1==$2 && $1==$4 && $3==WORD_SIZE && $5==WORD_SIZE &&
						inreg($1)==reg_pointer
with any_int-sconsts
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {post_inc_int, regvar($1, reg_pointer)}

pat sil LLP adp SLP $1==$2 && $1==$4 && $3==WORD_SIZE && inreg($1)==reg_pointer
with any_int-sconsts
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {post_inc_int, regvar($1, reg_pointer)}

pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-1 && $5==1 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{pre_dec1, regvar($1, reg_pointer)}

/* Normally,  LLP loi will be optimized to lil */
pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-2 && $5==2 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{pre_dec2, regvar($1, reg_pointer)}

pat LLP adp SLP LLP loi $1==$3 && $1==$4 && $2==0-4 && $5==4 &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{pre_dec4, regvar($1, reg_pointer)}

pat LLP adp SLP lil $1==$3 && $1==$4 && $2==0-WORD_SIZE &&
						inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
			yields	{pre_dec_int, regvar($1, reg_pointer)}

pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-1 && $5==1 &&
						inreg($1)==reg_pointer
with any1
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {pre_dec1, regvar($1, reg_pointer)}

#if WORD_SIZE!=2
pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-2 && $5==2 &&
						inreg($1)==reg_pointer
with any2
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {pre_dec2, regvar($1, reg_pointer)}
#else
pat LLP adp SLP LLP sti $1==$3 && $1==$4 && $2==0-4 && $5==4 &&
						inreg($1)==reg_pointer
with any4
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {pre_dec4, regvar($1, reg_pointer)}
#endif

pat LLP adp SLP sil $1==$3 && $1==$4 && $2==0-WORD_SIZE &&
						inreg($1)==reg_pointer
with any_int-sconsts
    kills allexceptcon, regvar($1, reg_pointer)
    gen move %1, {pre_dec_int, regvar($1, reg_pointer)}

pat LLP LLP adp SLP $1==$2 && $1==$4 && inreg($1)==reg_pointer && directadd($3)
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    uses AA_REG = {DLOCAL, $1}
    gen add_l {const4, $3}, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP LLP adp SLP $1==$2 && $1==$4 && inreg($1)==reg_pointer && directsub($3)
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    uses AA_REG = {DLOCAL, $1}
    gen sub_l {const4, 0-$3}, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP LLP adp SLP $1==$2 && $1==$4 && inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    uses AA_REG = {DLOCAL, $1}, DD_REG4 = {const4, $3}
    gen add_l %b, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP LLP adp SLP $1==$2 && $1==$4 && directadd($3)
    kills all_indir, DLOCAL %bd==$1
    uses AA_REG = {DLOCAL, $1}
    gen add_l {const4, $3}, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP LLP adp SLP $1==$2 && $1==$4 && directsub($3)
    kills all_indir, DLOCAL %bd==$1
    uses AA_REG = {DLOCAL, $1}
    gen sub_l {const4, 0-$3}, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP LLP adp SLP $1==$2 && $1==$4
    kills all_indir, DLOCAL %bd==$1
    uses AA_REG = {DLOCAL, $1}, DD_REG4 = {const4, $3}
    gen add_l %b, {DLOCAL, $1}
    killreg %a
			yields	%a

pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer && directadd($2)
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen add_l {const4, $2}, {DLOCAL, $1}

pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer && directsub($2)
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen sub_l {const4, 0-$2}, {DLOCAL, $1}

pat LLP adp SLP $1==$3 && inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    uses DD_REG4 = {const4, $2}
    gen add_l %a, {DLOCAL, $1}

pat LLP adp SLP $1==$3 && directadd($2)
    kills all_indir, DLOCAL %bd==$1
    gen add_l {const4, $2}, {DLOCAL, $1}

pat LLP adp SLP $1==$3 && directsub($2)
    kills all_indir, DLOCAL %bd==$1
    gen sub_l {const4, 0-$2}, {DLOCAL, $1}

pat LLP adp SLP $1==$3
    kills all_indir, DLOCAL %bd==$1
    uses DD_REG4 = {const4, $2}
    gen add_l %a, {DLOCAL, $1}

#if WORD_SIZE!=2
pat lil lil adp sil sti $1==$2 && $1==$4 && inreg($1)==reg_pointer && $5<=4
    with conreg
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}
    gen add_l {const, $3}, {indirect4, regvar($1, reg_pointer)}
    killreg %a
			yields	%1 %a		leaving sti $5

pat lil lil adp sil $1==$2 && $1==$4 && inreg($1)==reg_pointer
    kills allexceptcon
    uses AA_REG = {indirect4, regvar($1, reg_pointer)}
    gen add_l {const, $3}, {indirect4, regvar($1, reg_pointer)}
    killreg %a
			yields	%a

pat lil lil adp sil $1==$2 && $1==$4
    kills allexceptcon
    uses AA_REG, AA_REG = {LOCAL, $1}
    gen move {indirect4, %b}, %a
	add_l {const, $3}, {indirect4, %b}
	killreg %a
			yields	%a

pat lil adp sil $1==$3 && inreg($1)==reg_pointer
    kills allexceptcon
    gen add_l {const, $2}, {indirect4, regvar($1, reg_pointer)}

pat lil adp sil $1==$3 && inreg($1)!=reg_any
    kills allexceptcon
#if TBL68020 /* WORD_SIZE==4 */
    gen add_l {const, $2}, {ILOCAL,$1}
#else
    uses AA_REG = {LOCAL, $1}
    gen add_l {const, $2}, {indirect4, %a}
#endif
#endif /* WORD_SIZE==2 */

pat LEP LEP adp SEP $1==$2 && $1==$4
    kills posextern
    uses AA_REG = {absolute4, $1}
    gen add_l {const4, $3}, {absolute4, $1}
    killreg %a
			yields	%a

pat LEP adp SEP $1==$3
    kills posextern
    gen add_l {const4, $2}, {absolute4, $1}

pat loc and $1==255 && $2==WORD_SIZE
#if WORD_SIZE==2
    with exact absolute_int	yields {absolute1,%1.bd+1}
    with exact offsetted_int	yields {offsetted1,%1.reg,%1.bd+1}
    with exact LOCAL		yields {offsetted1,lb,%1.bd+1}
#else
    with exact absolute_int	yields {absolute1,%1.bd+3}
    with exact offsetted_int	yields {offsetted1,%1.reg,%1.bd+3}
    with exact LOCAL		yields {offsetted1,lb,%1.bd+3}
#endif
    with			yields {const, $1}	leaving and WORD_SIZE

/************************************************
 * Group 1: load instructions			*
 ************************************************/

pat loc $1==0		yields	{zero_const, $1}

pat loc small($1)	yields	{small_const, $1}

pat loc in_1($1)	yields	{bconst, $1}

pat loc			yields	{const, $1}

#if WORD_SIZE!=2
pat ldc				leaving loc 18 trp
#else
pat ldc highw($1)==0 && loww($1)==0	yields	{zero_const4, 0}

pat ldc highw($1)==0 && small(loww($1))	yields	{small_const4, loww($1)}

pat ldc highw($1)==0 && in_1(loww($1))	yields	{bconst4, loww($1)}

pat ldc			yields	{const4, $1}
#endif

pat LLP inreg($1)==reg_pointer
    kills pre_post %reg==regvar($1, reg_pointer)
			yields	{DLOCAL, $1}

pat lol			yields	{LOCAL, $1}

#if WORD_SIZE!=2
pat ldl				leaving lol $1+4 lol $1
#else
pat ldl			yields	{DLOCAL, $1}
#endif

pat loe			yields	{absolute_int, $1}

pat loe loe $1==$2		leaving loe $1 dup WORD_SIZE

/* replace ste loe by dup ste, but not if followed by a test ... */
proc steloezxx example ste loe zne
with any_int-sconsts
    kills posextern
    gen move_i %1, {absolute_int, $1}
	bxx* {llabel, $3}
with exact STACK
    kills posextern
    gen move_i {post_inc_int, sp}, {absolute_int, $1}
	bxx* {llabel, $3}

pat ste loe zlt $1==$2			call steloezxx("blt")
pat ste loe zle	$1==$2			call steloezxx("ble")
pat ste loe zeq	$1==$2			call steloezxx("beq")
pat ste loe zne	$1==$2			call steloezxx("bne")
pat ste loe zge	$1==$2			call steloezxx("bge")
pat ste loe zgt	$1==$2			call steloezxx("bgt")

pat ste loe $1==$2		leaving dup WORD_SIZE ste $1

pat lil inreg($1)==reg_pointer
    kills pre_post %reg==regvar($1, reg_pointer)
			yields	{indirect_int, regvar($1, reg_pointer)}
#if WORD_SIZE==4
pat lil inreg($1)==reg_any
    uses AA_REG = {DLOCAL, $1}
			yields  {indirect_int, %a}
#endif

pat lil
#if TBL68020
			yields	{ILOCAL, $1}
#else
    uses AA_REG = {DLOCAL, $1}
			yields	{indirect_int, %a}
#endif

	/* When using the 'offsetted' intructions regAregXcon cannot be used
	 * for the m68k[24]; there is no way of knowing about the size of
	 * %1.bd+$1, because expressions are not allowed in stack patterns, and
	 * this may lead to outputting too large displacements. With regAcon
	 * the chance that this will happen is very slim, because it can 
	 * have displacements of 16 bits. Besides, leaving out regAcon here
	 * would make it very hard to handle this instruction efficiently.
	 */
pat lof
with A_REG		yields	{offsetted_int, %1, $1}
with exact local_addr	yields	{LOCAL, %1.bd+$1}
with exact ext_addr	yields	{absolute_int, %1.bd+$1}
#ifndef TBL68020
with regAcon		yields	{offsetted_int, %1.reg, %1.bd+$1}
#else /* TBL68020 */
with exact regAcon	yields	{offsetted_int, %1.reg, %1.bd+$1}
with exact regAregXcon	yields	{index_off_int, %1.reg, %1.xreg, %1.sc, %1.bd+$1}
#ifdef FANCY_MODES
with exact offsetted4	yields	{OFF_off_int, %1.reg, %1.bd, $1}
with exact indirect	yields	{OFF_off_int, %1.reg, 0, $1}
with exact DLOCAL	yields	{OFF_off_int, lb, %1.bd, $1}
with exact off_con	yields	{OFF_off_int, %1.reg, %1.bd, %1.od+$1}
with exact index_off4	yields	{INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
with exact indoff_con	yields	{INDOFF_off_int,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact off_regXcon	yields	{OFF_indoff_int,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact absolute4	yields	{ABS_off_int, %1.bd, $1}
with exact abs_con	yields	{ABS_off_int, %1.bd, %1.od+$1}
with exact abs_regXcon	yields	{ABS_indoff_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact abs_index4	yields	{ABSIND_off_int, %1.sc, %1.xreg, %1.bd, $1}
with exact absind_con	yields	{ABSIND_off_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact ext_regX	yields	{abs_index_int, %1.sc, %1.xreg, %1.bd+$1}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

pat lal			yields	{local_addr, $1}

pat lae			yields	{ext_addr, $1}

pat lxl $1==0		yields	lb

pat lxl $1==1		yields	{DLOCAL, SL}

pat lxl $1==2
#if TBL68020 && FANCY_MODES
			yields	{OFF_off4, lb, SL, SL}
#else
    uses AA_REG = {DLOCAL, SL}
			yields	{offsetted4, %a, SL}
#endif

pat lxl $1==3
#if TBL68020 && FANCY_MODES
    uses AA_REG = {OFF_off4, lb, SL, SL}
#else
    uses AA_REG = {DLOCAL, SL}
    gen move_l {offsetted4, %a, SL}, %a
#endif
			yields	{offsetted4, %a, SL}

pat lxl $1>3
    uses AA_REG = {DLOCAL, SL},
	 DD_REG4 = {const, $1-2}
    gen 1: 
        move_l {offsetted4, %a, SL} ,%a
	dbf %b, {slabel, 1b}
			yields	%a

pat lxa $1==0		yields	{local_addr, SL}

pat lxa $1==1
#if TBL68020 && FANCY_MODES
			yields	{off_con, lb, SL, SL}
#else
    uses AA_REG = {DLOCAL, SL}
			yields	{regAcon, %a, SL}
#endif

pat  lxa $1==2
#if TBL68020 && FANCY_MODES
    uses AA_REG = {OFF_off4, lb, SL, SL}
#else
    uses AA_REG = {DLOCAL, SL}
    gen move_l {offsetted4, %a, SL}, %a
#endif
			yields	{regAcon, %a, SL}

pat lxa $1>2
    uses AA_REG = {DLOCAL, SL},
	 DD_REG4 = {const, $1-2}
    gen 1: 
        move_l {offsetted4, %a, SL} ,%a
	dbf %b, {slabel, 1b}
			yields	{regAcon, %a, SL}

pat loi $1==1
with A_REG		yields	{indirect1, %1}
with exact local_addr	yields	{offsetted1, lb, %1.bd}
with exact ext_addr	yields	{absolute1, %1.bd}
#ifndef TBL68020
with regAcon		yields	{offsetted1, %1.reg, %1.bd}
with regAregXcon	yields	{index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon	yields	{offsetted1, %1.reg, %1.bd}
with exact regAregXcon	yields	{index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
#ifdef FANCY_MODES
with exact indirect4	yields	{OFF_off1, %1.reg, 0, 0}
with exact offsetted4	yields	{OFF_off1, %1.reg, %1.bd, 0}
with exact LOCAL	yields	{OFF_off1, lb, %1.bd, 0}
with exact off_con	yields	{OFF_off1, %1.reg, %1.bd, %1.od}
with exact index_off4	yields	{INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con	yields	{INDOFF_off1,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon	yields	{OFF_indoff1,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4	yields	{ABS_off1, %1.bd, 0}
with exact abs_con	yields	{ABS_off1, %1.bd, %1.od}
with exact abs_regXcon	yields	{ABS_indoff1, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4	yields	{ABSIND_off1, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con	yields	{ABSIND_off1, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX	yields	{abs_index1, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

pat loi $1==2
with A_REG		yields	{indirect2, %1}
#if WORD_SIZE!=2
with exact local_addr	yields	{offsetted2, lb, %1.bd}
#else
with exact local_addr	yields	{LOCAL, %1.bd}
#endif
with exact ext_addr	yields	{absolute2, %1.bd}
#ifndef TBL68020
with regAcon		yields	{offsetted2, %1.reg, %1.bd}
with regAregXcon	yields	{index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon	yields	{offsetted2, %1.reg, %1.bd}
with exact regAregXcon	yields	{index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
#if WORD_SIZE==2
with exact DLOCAL	yields	{ILOCAL, %1.bd}
#endif
#ifdef FANCY_MODES
with exact indirect4	yields	{OFF_off2, %1.reg, 0, 0}
with exact offsetted4	yields	{OFF_off2, %1.reg, %1.bd, 0}
with exact LOCAL	yields	{OFF_off2, lb, %1.bd, 0}
with exact off_con	yields	{OFF_off2, %1.reg, %1.bd, %1.od}
with exact index_off4	yields	{INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con	yields	{INDOFF_off2,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon	yields	{OFF_indoff2,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4	yields	{ABS_off2, %1.bd, 0}
with exact abs_con	yields	{ABS_off2, %1.bd, %1.od}
with exact abs_regXcon	yields	{ABS_indoff2, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4	yields	{ABSIND_off2, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con	yields	{ABSIND_off2, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX	yields	{abs_index2, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

pat loi $1==4
with A_REG		yields	{indirect4, %1}
with exact local_addr	yields	{DLOCAL, %1.bd}
with exact ext_addr	yields	{absolute4, %1.bd}
#ifndef TBL68020
with regAcon		yields	{offsetted4, %1.reg, %1.bd}
with regAregXcon	yields	{index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon	yields	{offsetted4, %1.reg, %1.bd}
with exact regAregXcon	yields	{index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
#if WORD_SIZE==4
with exact LOCAL	yields	{ILOCAL, %1.bd}
#endif
#ifdef FANCY_MODES
with exact indirect4	yields	{OFF_off4, %1.reg, 0, 0}
with exact offsetted4	yields	{OFF_off4, %1.reg, %1.bd, 0}
with exact off_con	yields	{OFF_off4, %1.reg, %1.bd, %1.od}
with exact index_off4	yields	{INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con	yields	{INDOFF_off4,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon	yields	{OFF_indoff4,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4	yields	{ABS_off4, %1.bd, 0}
with exact abs_con	yields	{ABS_off4, %1.bd, %1.od}
with exact abs_regXcon	yields	{ABS_indoff4, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4	yields	{ABSIND_off4, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con	yields	{ABSIND_off4, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX	yields	{abs_index4, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

#if WORD_SIZE==2
pat loi $1==6
with AA_REG
			yields {offsetted2, %1, 4} {indirect4, %1}
with exact local_addr
			yields {offsetted2, lb, %1.bd+4} {offsetted4, lb, %1.bd}
with exact ext_addr
			yields {absolute2, %1.bd + 4} {absolute4, %1.bd}
#endif

pat loi $1==8
#if WORD_SIZE!=2
			    leaving ldf 0
#else
with AA_REG
			yields {offsetted4, %1, 4} {indirect4, %1}
with exact local_addr
			yields {offsetted4, lb, %1.bd+4} {offsetted4, lb, %1.bd}
with exact ext_addr
			yields {absolute4, %1.bd + 4} {absolute4, %1.bd}
#endif

#if WORD_SIZE==4
pat loi $1==3*WORD_SIZE
with AA_REG STACK
    kills ALL
    uses DD_REG4={const,$1}
    gen add_l %a, %1
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
	move_i {pre_dec_int, %1},{pre_dec_int, sp}

pat loi $1==4*WORD_SIZE
with AA_REG STACK
    kills ALL
    uses DD_REG4={const4,$1}
    gen add_l %a, %1
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
	move_i {pre_dec_int, %1},{pre_dec_int, sp}
#endif

pat loi $1>4*WORD_SIZE && $1/WORD_SIZE <= 65536
with AA_REG STACK
    kills ALL
    uses DD_REG4 = {const, $1/WORD_SIZE -1}
    gen add_l {const4, $1}, %1
	1:
	move_i {pre_dec_int, %1}, {pre_dec_int, sp}
	dbf %a, {slabel, 1b}

pat loi
with STACK
    kills ALL
    gen move_i {const,$1},{pre_dec_int, sp}
	jsr {absolute4, ".los"}

pat los $1==WORD_SIZE
with STACK
    kills ALL
    gen jsr {absolute4, ".los"}
#if WORD_SIZE==2
pat los $1==4
with STACK
    kills ALL
    gen jsr {absolute4, ".los4"}
#endif

pat lde
#if WORD_SIZE==2
			yields	{absolute4, $1}
#else
			yields	{absolute4, $1+4}
				{absolute4, $1}
#endif

pat ldf
#if WORD_SIZE==2
with A_REG		yields	{offsetted4, %1, $1}
with exact local_addr	yields	{DLOCAL, %1.bd+$1}
with regAcon		yields	{offsetted4, %1.reg, %1.bd+$1}
#else
with A_REG		yields	{offsetted4, %1, $1+4}
				{offsetted4, %1, $1}
with exact local_addr	yields	{LOCAL, %1.bd+$1+4}
				{LOCAL, %1.bd+$1}
with regAcon		yields	{offsetted4, %1.reg, %1.bd+$1+4}
				{offsetted4, %1.reg, %1.bd+$1}
#endif

pat lpi			yields	{ext_addr, $1}

/************************************************
 * Group 2: store instructions			*
 ************************************************/

pat stl inreg($1)==reg_any
with exact memory1-consts
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen	clr_i {LOCAL, $1}
	move_b %1, {dreg1, regvar($1,reg_any)}
#if WORD_SIZE==2
with any2
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen	move %1, {LOCAL, $1}
#else
with exact memory2-consts
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen	clr_i {LOCAL, $1}
	move_w %1, {dreg2, regvar($1,reg_any)}
with store4
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen move %1, {LOCAL, $1}
#endif
with exact STACK
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen move_i {post_inc_int, sp}, {LOCAL, $1}

pat SLP inreg($1)==reg_pointer
with any4
#if WORD_SIZE!=2
	    -sconsts4
#endif
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move %1, {areg, regvar($1, reg_pointer)}
with exact ext_addr
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move_l %1, {areg, regvar($1, reg_pointer)}
with address-ext_addr
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen lea %1, {areg, regvar($1, reg_pointer)}
with exact STACK
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move_l {post_inc4, sp}, {areg, regvar($1, reg_pointer)}

pat stl
with store_int-sconsts
    kills all_indir, LOCAL %bd==$1
    gen move %1, {LOCAL, $1}
with exact STACK
    kills all_indir, LOCAL %bd==$1
    gen move_i {post_inc_int,sp}, {LOCAL, $1}

pat ste
with store_int-sconsts
    kills posextern
    gen move %1, {absolute_int, $1}
with exact STACK
    kills posextern
    gen move_i {post_inc_int, sp}, {absolute_int, $1}

pat sil inreg($1)==reg_pointer
with store_int-sconsts
    kills allexceptcon
    gen move %1, {indirect_int, regvar($1, reg_pointer)}
with exact STACK
    kills allexceptcon
    gen move_i {post_inc_int, sp}, {indirect_int, regvar($1, reg_pointer)}

#if WORD_SIZE==4
pat sil inreg($1)==reg_any
with store_int-sconsts
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}
    gen move %1, {indirect_int, %a}
with exact STACK
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}
    gen move_i {post_inc_int, sp}, {indirect_int, %a}
#endif

pat sil
#if TBL68020
with store_int-sconsts
    kills allexceptcon
    gen move %1, {ILOCAL, $1}
with exact STACK
    kills allexceptcon
    gen move_i {post_inc_int, sp}, {ILOCAL, $1}
#else
with store_int-sconsts
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}
    gen move %1, {indirect_int, %a}
with exact STACK
    kills allexceptcon
    uses AA_REG = {DLOCAL, $1}
    gen move_i {post_inc_int, sp}, {indirect_int, %a}
#endif

pat stf
with A_REG store_int-sconsts
    kills allexceptcon
    gen move %2, {offsetted_int, %1, $1}
with exact any4 STACK
    kills allexceptcon
    uses AA_REG = %1
    gen move_i {post_inc_int, sp}, {offsetted_int, %a, $1}
with exact STACK
    kills allexceptcon
    uses AA_REG
    gen move_l {post_inc4, sp}, %a
	move_i {post_inc_int, sp}, {offsetted_int, %a, $1}
with exact local_addr store_int
    kills allexceptcon
    gen move %2, {LOCAL, %1.bd+$1}
with exact ext_addr store_int
    kills allexceptcon
    gen move %2, {absolute_int, %1.bd+$1}
#if TBL68000
#if WORD_SIZE==4
with regAcon store_int
    kills allexceptcon
    gen move %2, {offsetted_int, %1.reg, %1.bd+$1}
#endif
#else /* TBL68020 */
with exact regAcon store_int
    kills allexceptcon
    gen move %2, {offsetted_int, %1.reg, %1.bd+$1}
with exact regAregXcon store_int
    kills allexceptcon
    gen move %2, {index_off_int, %1.reg, %1.xreg, %1.sc, %1.bd+$1}
#ifdef FANCY_MODES
with exact indirect4 store_int
    kills allexceptcon
    gen move %2, {OFF_off_int, %1.reg, 0, $1}
with exact offsetted4 store_int
    kills allexceptcon
    gen move %2, {OFF_off_int, %1.reg, %1.bd, $1}
with exact DLOCAL store_int
    kills allexceptcon
    gen move %2, {OFF_off_int, lb, %1.bd, $1}
with exact off_con store_int
    kills allexceptcon
    gen move %2, {OFF_off_int, %1.reg, %1.bd, %1.od+$1}
with exact index_off4 store_int
    kills allexceptcon
    gen move %2, {INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
with exact indoff_con store_int
    kills allexceptcon
    gen move %2, {INDOFF_off_int, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact off_regXcon store_int
    kills allexceptcon
    gen move %2, {OFF_indoff_int, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact absolute4 store_int
    kills allexceptcon
    gen move %2, {ABS_off_int, %1.bd, $1}
with exact abs_con store_int
    kills allexceptcon
    gen move %2, {ABS_off_int, %1.bd, %1.od+$1}
with exact abs_regXcon store_int
    kills allexceptcon
    gen move %2, {ABS_indoff_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact abs_index4 store_int
    kills allexceptcon
    gen move %2, {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, $1}
with exact absind_con store_int
    kills allexceptcon
    gen move %2, {ABSIND_off_int, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact ext_regX store_int
    kills allexceptcon
    gen move %2, {abs_index_int, %1.sc, %1.xreg, %1.bd+$1}
#endif	/* FANCY_MODES */
#endif /* TBL68020 */

pat sti $1==1
with A_REG any1
    kills allexceptcon
    gen move %2, {indirect1, %1}
with local_addr any1
    kills allexceptcon
    gen move %2, {offsetted1, lb, %1.bd}
with exact ext_addr any1
    kills allexceptcon
    gen move %2, {absolute1, %1.bd}
#ifndef TBL68020
with regAcon any1
    kills allexceptcon
    gen move %2, {offsetted1, %1.reg, %1.bd}
with regAregXcon any1
    kills allexceptcon
    gen move %2, {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon any1
    kills allexceptcon
    gen move %2, {offsetted1, %1.reg, %1.bd}
with exact regAregXcon any1
    kills allexceptcon
    gen move %2, {index_off1, %1.reg, %1.xreg, %1.sc, %1.bd}
#ifdef FANCY_MODES
with exact indirect4 any1
    kills allexceptcon
    gen move %2, {OFF_off1, %1.reg, 0, 0}
with exact offsetted4 any1
    kills allexceptcon
    gen move %2, {OFF_off1, %1.reg, %1.bd, 0}
with exact LOCAL any1
    kills allexceptcon
    gen move %2, {OFF_off1, lb, %1.bd, 0}
with exact off_con any1
    kills allexceptcon
    gen move %2, {OFF_off1, %1.reg, %1.bd, %1.od}
with exact index_off4 any1
    kills allexceptcon
    gen move %2, {INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con any1
    kills allexceptcon
    gen move %2, {INDOFF_off1, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon any1
    kills allexceptcon
    gen move %2, {OFF_indoff1, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4 any1
    kills allexceptcon
    gen move %2, {ABS_off1, %1.bd, 0}
with exact abs_con any1
    kills allexceptcon
    gen move %2, {ABS_off1, %1.bd, %1.od}
with exact abs_regXcon any1
    kills allexceptcon
    gen move %2, {ABS_indoff1, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4 any1
    kills allexceptcon
    gen move %2, {ABSIND_off1, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con any1
    kills allexceptcon
    gen move %2, {ABSIND_off1, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX any1
    kills allexceptcon
    gen move %2, {abs_index1, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

pat sti $1==2
with A_REG any2
    kills allexceptcon
    gen move %2, {indirect2, %1}
with local_addr any2
    kills allexceptcon
    gen move %2, {offsetted2, lb, %1.bd}
with exact ext_addr any2
    kills allexceptcon
    gen move %2, {absolute2, %1.bd}
#ifndef TBL68020
with regAcon any2
    kills allexceptcon
    gen move %2, {offsetted2, %1.reg, %1.bd}
with regAregXcon any2
    kills allexceptcon
    gen move %2, {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon any2
    kills allexceptcon
    gen move %2, {offsetted2, %1.reg, %1.bd}
with exact regAregXcon any2
    kills allexceptcon
    gen move %2, {index_off2, %1.reg, %1.xreg, %1.sc, %1.bd}
#if WORD_SIZE==2
with exact DLOCAL any2
    kills allexceptcon
    gen move %2, {ILOCAL, %1.bd}
#endif
#ifdef FANCY_MODES
with exact indirect4 any2
    kills allexceptcon
    gen move %2, {OFF_off2, %1.reg, 0, 0}
with exact offsetted4 any2
    kills allexceptcon
    gen move %2, {OFF_off2, %1.reg, %1.bd, 0}
with exact LOCAL any2
    kills allexceptcon
    gen move %2, {OFF_off2, lb, %1.bd, 0}
with exact off_con any2
    kills allexceptcon
    gen move %2, {OFF_off2, %1.reg, %1.bd, %1.od}
with exact index_off4 any2
    kills allexceptcon
    gen move %2, {INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con any2
    kills allexceptcon
    gen move %2, {INDOFF_off2, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon any2
    kills allexceptcon
    gen move %2, {OFF_indoff2, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4 any2
    kills allexceptcon
    gen move %2, {ABS_off2, %1.bd, 0}
with exact abs_con any2
    kills allexceptcon
    gen move %2, {ABS_off2, %1.bd, %1.od}
with exact abs_regXcon any2
    kills allexceptcon
    gen move %2, {ABS_indoff2, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4 any2
    kills allexceptcon
    gen move %2, {ABSIND_off2, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con any2
    kills allexceptcon
    gen move %2, {ABSIND_off2, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX any2
    kills allexceptcon
    gen move %2, {abs_index2, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

pat sti $1==4
with A_REG store4-sconsts4
    kills allexceptcon
    gen move %2, {indirect4, %1}
with exact any4 STACK
    kills allexceptcon
    uses AA_REG = %1
    gen move_l {post_inc4, sp}, {indirect4, %a}
with exact STACK
    kills allexceptcon
    uses AA_REG
    gen move_l {post_inc4, sp}, %a
	move_l {post_inc4, sp}, {indirect4, %a}
with exact local_addr store4
    kills allexceptcon
    gen move %2, {DLOCAL, %1.bd}
with exact ext_addr store4
    kills allexceptcon
    gen move %2, {absolute4, %1.bd}
#ifndef TBL68020
with regAcon store4-sconsts4
    kills allexceptcon
    gen move %2, {offsetted4, %1.reg, %1.bd}
with regAregXcon store4-sconsts4
    kills allexceptcon
    gen move %2, {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
#else /* TBL68020 */
with exact regAcon store4
    kills allexceptcon
    gen move %2, {offsetted4, %1.reg, %1.bd}
with exact regAregXcon store4
    kills allexceptcon
    gen move %2, {index_off4, %1.reg, %1.xreg, %1.sc, %1.bd}
#if WORD_SIZE==4
with exact LOCAL store4
    kills allexceptcon
    gen move %2, {ILOCAL, %1.bd}
#endif
#ifdef FANCY_MODES
with exact indirect4 store4
    kills allexceptcon
    gen move %2, {OFF_off4, %1.reg, 0, 0}
with exact offsetted4 store4
    kills allexceptcon
    gen move %2, {OFF_off4, %1.reg, %1.bd, 0}
with exact off_con store4
    kills allexceptcon
    gen move %2, {OFF_off4, %1.reg, %1.bd, %1.od}
with exact index_off4 store4
    kills allexceptcon
    gen move %2, {INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, 0}
with exact indoff_con store4
    kills allexceptcon
    gen move %2, {INDOFF_off4, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact off_regXcon store4
    kills allexceptcon
    gen move %2, {OFF_indoff4, %1.reg, %1.xreg, %1.sc, %1.bd, %1.od}
with exact absolute4 store4
    kills allexceptcon
    gen move %2, {ABS_off4, %1.bd, 0}
with exact abs_con store4
    kills allexceptcon
    gen move %2, {ABS_off4, %1.bd, %1.od}
with exact abs_regXcon store4
    kills allexceptcon
    gen move %2, {ABS_indoff4, %1.sc, %1.xreg, %1.bd, %1.od}
with exact abs_index4 store4
    kills allexceptcon
    gen move %2, {ABSIND_off4, %1.sc, %1.xreg, %1.bd, 0}
with exact absind_con store4
    kills allexceptcon
    gen move %2, {ABSIND_off4, %1.sc, %1.xreg, %1.bd, %1.od}
with exact ext_regX store4
    kills allexceptcon
    gen move %2, {abs_index4, %1.sc, %1.xreg, %1.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

#if WORD_SIZE==2
pat sti $1==6
with A_REG any4 any2
    kills ALL
    gen move %2, {indirect4, %1}
	move %3, {offsetted2, %1, 4}
with AA_REG any4 any2
    kills ALL
    gen move %2, {post_inc4, %1}
	move %3, {post_inc2, %1}
with exact A_REG STACK
    kills ALL
    gen move_l {post_inc4, sp}, {indirect4, %1}
	move_w {post_inc2, sp}, {offsetted2, %1, 4}
with exact AA_REG STACK
    kills ALL
    gen move_l {post_inc4, sp}, {post_inc4, %1}
	move_w {post_inc2, sp}, {post_inc2, %1}
#endif

pat sti $1==8
#if WORD_SIZE!=2
			leaving sdf 0
#else
with AA_REG any4-pre_post any4-pre_post
    kills ALL
    gen move_l %2,{indirect4, %1}
	move_l %3,{offsetted4, %1, 4}
with exact local_addr any4-pre_post any4-pre_post
    kills ALL
    gen move_l %2,{offsetted4, lb, %1.bd}
	move_l %3,{offsetted4, lb, %1.bd+4}
with exact ext_addr any4-pre_post any4-pre_post
    kills ALL
    gen move_l %2,{absolute4, %1.bd}
	move_l %3,{absolute4, %1.bd+4}
#endif


#if WORD_SIZE==4
pat sti $1==3*WORD_SIZE
    with AA_REG STACK
    kills ALL
    gen	move_i {post_inc_int, sp},{post_inc_int,%1}
    	move_i {post_inc_int, sp},{post_inc_int,%1}
    	move_i {post_inc_int, sp},{post_inc_int,%1}

pat sti $1==4*WORD_SIZE
    with AA_REG STACK
    kills ALL
    gen	move_i {post_inc_int, sp},{post_inc_int,%1}
	move_i {post_inc_int, sp},{post_inc_int,%1}
	move_i {post_inc_int, sp},{post_inc_int,%1}
	move_i {post_inc_int, sp},{post_inc_int,%1}
#endif

pat sti $1>4*WORD_SIZE && $1/WORD_SIZE <= 65536
with AA_REG STACK
    kills ALL
    uses DD_REG4 = {const, $1/WORD_SIZE -1}
    gen 1:
	move_i {post_inc_int, sp}, {post_inc_int, %1}
	dbf %a, {slabel, 1b}

pat sti
with STACK
    kills ALL
    gen	move_i {const, $1}, {pre_dec_int, sp}
	jsr {absolute4, ".sts"}

pat sts $1==WORD_SIZE
with STACK
    kills ALL
    gen jsr {absolute4, ".sts"}
#if WORD_SIZE==2
pat sts $1==4
with STACK
    kills ALL
    gen jsr {absolute4, ".sts4"}
#endif

#if WORD_SIZE==2
pat sdl
with store4-sconsts4
    kills all_indir, DLOCAL %bd==$1
    gen move %1, {DLOCAL, $1}
with exact STACK
    kills all_indir, DLOCAL %bd==$1
    gen move_l {post_inc4,sp}, {DLOCAL, $1}
#else
pat sdl
with any4-sconsts any4-sconsts
    kills all_indir, LOCAL %bd==$1
    gen move %1, {LOCAL, $1} 
        move %2, {LOCAL, $1+4}
#if TBL68881
with exact FD_REG
    kills all_indir, LOCAL %bd==$1
    gen	fmove_d %1, {LOCAL, $1}
#endif
with exact STACK
    kills all_indir, LOCAL %bd==$1
    gen move_l {post_inc4, sp}, {LOCAL,$1}
        move_l {post_inc4, sp}, {LOCAL,$1+4}
#endif /* WORD_SIZE==2 */

pat sde
#if WORD_SIZE==2
with any4-sconsts4
    kills posextern
    gen move_l %1, {absolute4, $1}
with exact STACK
    kills posextern
    gen move_l {post_inc4, sp}, {absolute4, $1}
#else
with any4-sconsts any4-sconsts
    kills posextern
    gen move %1, {absolute4, $1}
	move %2, {absolute4, $1+4}
#if TBL68881
with exact FD_REG
    kills posextern
    gen	fmove_d %1, {absolute4, $1}
#endif
with exact STACK
    kills posextern
    gen move_l {post_inc4, sp}, {absolute4,$1}
        move_l {post_inc4, sp}, {absolute4,$1+4}
#endif

pat sdf
#if WORD_SIZE==2
with A_REG any4-sconsts4
    kills allexceptcon
    gen move_l %2, {offsetted4, %1, $1}
with exact A_REG STACK
    kills allexceptcon
    gen move_l {post_inc4, sp}, {offsetted4, %1, $1}
#else
with A_REG any4-sconsts any4-sconsts
    kills allexceptcon
    gen move %2, {offsetted4, %1, $1}
	move %3, {offsetted4, %1, $1+4}
with exact local_addr any4 any4
    kills allexceptcon
    gen move %2, {LOCAL, %1.bd+$1}
	move %3, {LOCAL, %1.bd+$1+4}
with regAcon any4-sconsts any4-sconsts
    kills allexceptcon
    gen move %2, {offsetted4, %1.reg, %1.bd+$1}
	move %3, {offsetted4, %1.reg, %1.bd+$1+4}
#endif



/************************************************
 * Group 3: integer arithmetic.			*
 ************************************************/

#if WORD_SIZE==2
pat adi $1==2
with any2-bconst DD_REG
    gen add_w %1, %2	yields	%2
with DD_REG any2-DD_REG-bconst
    gen add_w %2, %1	yields	%1
with exact any2 STACK
    uses reusing %1,DD_REG=%1
    gen add_w {post_inc2, sp}, %a
			yields	%a
#endif

pat adi $1==4
with any4-bconst4 DD_REG4
    gen add_l %1, %2	yields	%2
with DD_REG4 any4-DD_REG4-bconst4
    gen add_l %2, %1	yields	%1
with exact any4 STACK
    uses reusing %1,DD_REG4=%1
    gen add_l {post_inc4, sp}, %a
			yields	%a

#if WORD_SIZE==2
pat sbi $1==2
with any2-bconst DD_REG
    gen sub_w %1, %2	yields	%2
with DD_REG any2-DD_REG-bconst
    gen sub_w %2, %1
	neg_w %1	yields	%1
with exact any2 STACK
    uses reusing %1,DD_REG=%1
    gen sub_w {post_inc2, sp}, %a
	neg_w %a	yields	%a
#endif

pat sbi $1==4
with any4-bconst4 DD_REG4
    gen sub_l %1, %2	yields	%2
with DD_REG4 any4-DD_REG4-bconst4
    gen sub_l %2, %1
	neg_l %1	yields	%1
with exact any4 STACK
    uses reusing %1,DD_REG4=%1
    gen sub_l {post_inc4, sp}, %a
	neg_l %a	yields	%a
with any4-bconst4 AA_REG
    gen sub_l %1, %2	yields	%2

#if WORD_SIZE==2
pat loc loc cii ldc mli $1==2 && $2==4 && highw($4)==0 && loww($4)>0 && $5==4
with any2-pre_post
    uses reusing %1, DD_REG4
    gen move %1, %a.1
	muls_w {const, loww($4)}, %a.1
					yields %a

pat mli $1==2
with any2-pre_post any2-pre_post
    uses reusing %2,DD_REG = %2
    gen muls_w %1, %a	yields	%a
#endif

pat mli $1==4
#ifdef TBL68020
with data4 DD_REG4
    gen muls_l %1, %2	yields	%2
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".mli"}
			yields	dl1
#endif

#if WORD_SIZE==2
pat dvi $1==2
with data2-sconsts DD_REG
    gen ext_l %2
	divs_w %1, %2
			yields	%2
#endif

pat dvi $1==4
#ifdef TBL68020
with data4-sconsts4 DD_REG4
    gen divs_l %1, %2	yields	%2
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".dvi"}
			yields	dl1
#endif /* TBL68020 */

#if WORD_SIZE==2
pat rmi $1==2
with data2-sconsts DD_REG
    gen ext_l %2
	divs_w %1, %2
	swap %2
	killreg %2
			yields	%2
#endif

pat rmi $1==4
#ifdef TBL68020
with data4-sconsts4 DD_REG4
    uses DD_REG4
    gen divsl_l %1, {DREG_pair, %a, %2}
	killreg %2
		/* !!!! contents of %2 have changed: make this known to cg */
			yields	%a
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".dvi"}
			yields	dl2
#endif /* TBL68020 */

#if WORD_SIZE==2
pat ngi $1==2
with DD_REG
    gen neg_w %1	yields	%1
#endif

pat ngi $1==4
with DD_REG4
    gen neg_l %1	yields	%1

#if WORD_SIZE==2
pat sli $1==2
with shconreg DD_REG
    gen asl_w %1, %2	yields	%2
#endif

pat sli $1==4
with shconreg DD_REG4
    gen asl_l %1, %2	yields	%2

#if WORD_SIZE==2
pat sri $1==2
with shconreg DD_REG
    gen asr_w %1, %2	yields	%2
#endif

pat sri $1==4
with shconreg DD_REG4
    gen asr_l %1, %2	yields	%2

/************************************************
 * Group 4: unsigned arithmetic.		*
 ************************************************/

pat adu				leaving adi $1

pat sbu				leaving sbi $1

#if WORD_SIZE==2
pat mlu $1==2
with any2-pre_post any2-pre_post
    uses reusing %2,DD_REG = %2
    gen mulu_w %1, %a	yields	%a
#endif

pat mlu $1==4
#ifdef TBL68020
with data4-sconsts4 DD_REG4
    gen mulu_l %1, %2	yields	%2
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".mlu"}
			yields	dl1
#endif /* TBL68020 */

#if WORD_SIZE==2
pat dvu $1==2
with data2-sconsts data2
    uses DD_REG4 = {zero_const4,0}
    gen move %2,%a.1
	divu_w %1, %a.1			yields %a.1
#endif

pat dvu $1==4
#ifdef TBL68020
with data4-sconsts4 DD_REG4
    gen divu_l %1, %2	yields	%2
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".dvu"}
			yields	dl1
#endif /* TBL68020 */

#if WORD_SIZE==2
pat rmu $1==2
with data2-sconsts data2
    uses DD_REG4 = {zero_const4, 0}
    gen move %2,%a.1
	divu_w %1, %a.1
	swap %a.1
	killreg %a
			yields	%a.1
#endif

pat rmu $1==4
#ifdef TBL68020
with data4-sconsts4 DD_REG4
    uses DD_REG4
    gen divul_l %1, {DREG_pair, %a, %2}
	killreg %2
		/* !!!! contents of %2 have changed: make this known to cg */
			yields	%a
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".dvu"}
			yields	dl2
#endif /* TBL68020 */

pat slu				leaving sli $1

#if WORD_SIZE==2
pat sru $1==2
with shconreg DD_REG
    gen lsr_w %1, %2	yields %2
#endif

pat sru $1==4
with shconreg DD_REG4
    gen lsr_l %1, %2	yields	%2

/************************************************
 * Group 5: floating point arithmetic		*
 ************************************************/

/* Floating point stuff
 * Arithmetic instructions
 */
 
#if TBL68881
pat adf stl $1==4
    with FS_REG STACK
    gen fadd_s {post_inc4,sp},%1	yields %1	leaving stl $2
pat adf sdl $1==8
    with FD_REG STACK
    gen fadd_d {post_inc4,sp},%1	yields %1	leaving sdl $2
pat sbf stl $1==4
    with FS_REG FS_REG STACK
    gen fsub %1,%2			yields %2	leaving stl $2
pat sbf sdl $1==8
    with FD_REG FD_REG STACK
    gen fsub %1,%2			yields %2	leaving sdl $2
pat mlf stl $1==4
    with FS_REG STACK
    gen fmul_s {post_inc4,sp},%1	yields %1	leaving stl $2
pat mlf sdl $1==8
    with FD_REG STACK
    gen fmul_d {post_inc4,sp},%1	yields %1	leaving sdl $2
pat dvf stl $1==4
    with FS_REG FS_REG STACK
    gen fdiv %1,%2			yields %2	leaving stl $2
pat dvf sdl $1==8
    with FD_REG FD_REG STACK
    gen fdiv %1,%2			yields %2	leaving sdl $2
pat ngf stl $1==4
    with FS_REG STACK
    gen fneg %1				yields %1	leaving stl $2
pat ngf sdl $1==8
    with FD_REG STACK
    gen fneg %1				yields %1	leaving sdl $2

pat adf ste $1==4
    with FS_REG STACK
    gen fadd_s {post_inc4,sp},%1	yields %1	leaving ste $2
pat adf sde $1==8
    with FD_REG STACK
    gen fadd_d {post_inc4,sp},%1	yields %1	leaving sde $2
pat sbf ste $1==4
    with FS_REG FS_REG STACK
    gen fsub %1,%2			yields %2	leaving ste $2
pat sbf sde $1==8
    with FD_REG FD_REG STACK
    gen fsub %1,%2			yields %2	leaving sde $2
pat mlf ste $1==4
    with FS_REG STACK
    gen fmul_s {post_inc4,sp},%1	yields %1	leaving ste $2
pat mlf sde $1==8
    with FD_REG STACK
    gen fmul_d {post_inc4,sp},%1	yields %1	leaving sde $2
pat dvf ste $1==4
    with FS_REG FS_REG STACK
    gen fdiv %1,%2			yields %2	leaving ste $2
pat dvf sde $1==8
    with FD_REG FD_REG STACK
    gen fdiv %1,%2			yields %2	leaving sde $2
pat ngf ste $1==4
    with FS_REG STACK
    gen fneg %1				yields %1	leaving ste $2
pat ngf sde $1==8
    with FD_REG STACK
    gen fneg %1				yields %1	leaving sde $2

pat adf $1==4
    with FS_REG STACK
    gen fadd_s {indirect4,sp},%1
	fmove_s %1,{indirect4,sp}
pat adf $1==8
    with FD_REG STACK
    gen fadd_d {indirect4,sp},%1
	fmove_d %1,{indirect4,sp}
pat sbf $1==4
    with FS_REG FS_REG STACK
    gen fsub %1,%2
	fmove_s %2,{pre_dec4,sp}
pat sbf $1==8
    with FD_REG FD_REG STACK
    gen fsub %1,%2
	fmove_d %2,{pre_dec4,sp}
pat mlf $1==4
    with FS_REG STACK
    gen fmul_s {indirect4,sp},%1
	fmove_s %1,{indirect4,sp}
pat mlf $1==8
    with FD_REG STACK
    gen fmul_d {indirect4,sp},%1
	fmove_d %1,{indirect4,sp}
pat dvf $1==4
    with FS_REG FS_REG STACK
    gen fdiv %1,%2
	fmove_s %2,{pre_dec4,sp}
pat dvf $1==8
    with FD_REG FD_REG STACK
    gen fdiv %1,%2
	fmove_d %2,{pre_dec4,sp}
pat ngf $1==4
    with FS_REG STACK
    gen fneg %1
	fmove_s %1,{pre_dec4,sp}
pat ngf $1==8
    with FD_REG STACK
    gen fneg %1
	fmove_d %1,{pre_dec4,sp}
pat fif $1==4
    with FS_REG FS_REG STACK
    gen fmul %1,%2
        fintrz %2,%1
	fsub %1,%2
	fmove_s %2,{pre_dec4,sp}
	fmove_s %1,{pre_dec4,sp}
pat fif $1==8
    with FD_REG FD_REG STACK
    gen fmul %1,%2
        fintrz %2,%1
	fsub %1,%2
	fmove_d %2,{pre_dec4,sp}
	fmove_d %1,{pre_dec4,sp}
#else
pat adf $1==4	leaving  cal ".adf4" asp 4
pat adf $1==8	leaving  cal ".adf8" asp 8
pat sbf $1==4	leaving  cal ".sbf4" asp 4
pat sbf $1==8	leaving  cal ".sbf8" asp 8
pat mlf $1==4	leaving  cal ".mlf4" asp 4
pat mlf $1==8	leaving  cal ".mlf8" asp 8
pat dvf $1==4	leaving  cal ".dvf4" asp 4
pat dvf $1==8	leaving  cal ".dvf8" asp 8
pat ngf $1==4	leaving  cal ".ngf4"
pat ngf $1==8	leaving  cal ".ngf8"
pat fif $1==4	leaving  lor 1 cal ".fif4" asp 4
pat fif $1==8	leaving  lor 1 cal ".fif8" asp 4
#endif
#if WORD_SIZE==2
pat fef $1==4	leaving  lor 1 adp 0-2 cal ".fef4" asp 2
pat fef $1==8	leaving	 lor 1 adp 0-2 cal ".fef8" asp 2
#else
pat fef $1==4	leaving  lor 1 adp 0-4 cal ".fef4"
pat fef $1==8	leaving	 lor 1 adp 0-4 cal ".fef8"
#endif

/************************************************
 * Group 6: pointer arithmetic			*
 ************************************************/

pat adp $1==0		/* skip; array instructions might 'leave' this */

pat adp
with A_REG		yields	{t_regAcon, %1, $1}
with exact local_addr	yields	{local_addr, %1.bd+$1}
with exact ext_addr	yields	{ext_addr, %1.bd+$1}
with exact regAcon + t_regAcon
			yields	{t_regAcon, %1.reg, %1.bd+$1}
with exact regAregXcon + t_regAregXcon
			yields	{t_regAregXcon,%1.reg, %1.xreg, %1.sc, %1.bd+$1}
#if TBL68020 && FANCY_MODES
with exact indirect4	yields	{off_con, %1.reg, 0, $1}
with exact LOCAL	yields	{off_con, lb, %1.bd, $1}
with exact offsetted4	yields	{off_con, %1.reg, %1.bd, $1}
with exact off_con	yields	{off_con, %1.reg, %1.bd, %1.od+$1}
with exact index_off4	yields	{indoff_con, %1.reg, %1.xreg, %1.sc, %1.bd, $1}
with exact indoff_con	yields	{indoff_con,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact off_regXcon	yields	{off_regXcon,
					%1.reg, %1.xreg, %1.sc, %1.bd, %1.od+$1}
with exact absolute4	yields	{abs_con, %1.bd, $1}
with exact abs_con	yields	{abs_con, %1.bd, %1.od+$1}
with exact abs_regXcon	yields	{abs_regXcon, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact abs_index4	yields	{absind_con, %1.sc, %1.xreg, %1.bd, $1}
with exact absind_con	yields	{absind_con, %1.sc, %1.xreg, %1.bd, %1.od+$1}
with exact ext_regX	yields	{ext_regX, %1.sc, %1.xreg, %1.bd+$1}
#endif

pat ads cmp $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving cmu 4
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving cmu 4
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving cmu 4
#endif

#if WORD_SIZE!=2
pat ads bne $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving bne $2
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving bne $2
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving bne $2
#endif

pat ads beq $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving beq $2
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving beq $2
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving beq $2
#endif

pat ads LEP bne $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LEP $2 bne $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LEP $2 bne $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving loe $2 bne $3
#endif

pat ads LEP beq $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LEP $2 beq $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LEP $2 beq $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving loe $2 beq $3
#endif

pat ads LEP cmp $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LEP $2 cmu 4
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LEP $2 cmu 4
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving LEP $2 cmu 4
#endif

pat ads lae bne $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lae $2 bne $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lae $2 bne $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lae $2 bne $3
#endif

pat ads lae beq $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lae $2 beq $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lae $2 beq $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lae $2 beq $3
#endif
#endif	/* WORD_SIZE==2 */

pat ads lae cmp $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lae $2 cmu 4
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lae $2 cmu 4
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lae $2 cmu 4
#endif

#if WORD_SIZE!=2
pat ads lal bne $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lal $2 bne $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lal $2 bne $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lal $2 bne $3
#endif

pat ads lal beq $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lal $2 beq $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lal $2 beq $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lal $2 beq $3
#endif

pat ads lal cmp $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving lal $2 cmu 4
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving lal $2 cmu 4
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lal $2 cmu 4
#endif

pat ads LLP bne $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LLP $2 bne $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LLP $2 bne $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lol $2 bne $3
#endif

pat ads LLP beq $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LLP $2 beq $3
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LLP $2 beq $3
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lol $2 beq $3
#endif
#endif /* WORD_SIZE==2 */

pat ads LLP cmp $1==4
with DD_REG4 any4
     gen add_l %2, %1	yields	%1	leaving LLP $2 cmu 4
with any4 DD_REG4
     gen add_l %1, %2	yields	%2	leaving LLP $2 cmu 4
#ifdef TBL68020
with regX AA_REG
     gen move {regAregXcon, %2, %1.xreg, %1.sc, 0},%2
			yields	%2	leaving lol $2 cmu 4
#endif

#if WORD_SIZE==2
pat ads $1==2
			leaving loc 2 loc 4 cii ads 4
#endif

pat ads $1==4
with D_REG4 A_REG	yields	{regAregXcon, %2, %1, 1, 0}
with D_REG4 regAcon + t_regAcon
			yields	{t_regAregXcon, %2.reg, %1, 1, %2.bd}
with D_REG4 local_addr	yields	{t_regAregXcon, lb, %1, 1, %2.bd}
with any4 AA_REG
    gen add_l %1, %2	yields	%2

#ifdef TBL68020

with D_REG4		yields	{regX, 1, %1}
				leaving ads 4
with regX A_REG		yields	{regAregXcon, %2, %1.xreg, %1.sc, 0}
with exact regX regAcon	yields	{regAregXcon, %2.reg, %1.xreg, %1.sc, %2.bd}
with exact regX local_addr
			yields	{regAregXcon, lb, %1.xreg, %1.sc, %2.bd}
#ifdef FANCY_MODES
with exact regX indirect4
			yields	{off_regXcon, %2.reg, %1.xreg,%1.sc,0,0}
with exact regX offsetted4
			yields	{off_regXcon, %2.reg, %1.xreg, %1.sc, %2.bd, 0}
with exact regX DLOCAL	yields	{off_regXcon, lb, %1.xreg, %1.sc, %2.bd, 0}
with exact regX off_con	yields	{off_regXcon, %2.reg, %1.xreg,%1.sc,%2.bd,%2.od}
with exact regX ext_addr
			yields	{ext_regX, %1.sc, %1.xreg, %2.bd}
with exact regX absolute4
			yields	{abs_regXcon, %1.sc, %1.xreg, %2.bd, 0}
with exact regX abs_con	yields	{abs_regXcon, %1.sc, %1.xreg, %2.bd, %2.od}
with exact indirect4 ext_addr
			yields	{off_con, %1.reg, 0, %2.bd}
with exact offsetted4 ext_addr
			yields	{off_con, %1.reg, %1.bd, %2.bd}
with exact LOCAL ext_addr
			yields	{off_con, lb, %1.bd, %2.bd}
with exact index_off4 ext_addr
			yields	{indoff_con, %1.reg, %1.xreg, %1.sc,%1.bd,%2.bd}
with exact absolute4 ext_addr
			yields	{abs_con, %1.bd, %2.bd}
with exact abs_index4 ext_addr
			yields	{absind_con, %1.sc, %1.xreg, %1.bd, %2.bd}
with exact indirect4 ext_regX
			yields	{off_regXcon, %1.reg, %2.xreg, %2.sc, 0, %2.bd}
with exact offsetted4 ext_regX
			yields	{off_regXcon, %1.reg, %2.xreg,%2.sc,%1.bd,%2.bd}
with exact LOCAL ext_regX
			yields	{off_regXcon, lb, %2.xreg, %2.sc, %1.bd, %2.bd}
with exact absolute4 ext_regX
			yields	{abs_regXcon, %2.sc, %2.xreg, %1.bd, %2.bd}
#endif /* FANCY_MODES */
#endif /* TBL68020 */

	/* I WOULD ALSO LIKE THIS:
	 * 	pat ads
	 * 	with const			leaving adp %1.num
	 * BUT THAT DOESN'T WORK.
	 */

#if WORD_SIZE==2
pat sbs $1==2
			leaving sbs 4 loc 4 loc 2 cii
#endif

pat sbs $1==4			leaving sbi 4

/* regX type OK ??? */
#ifdef TBL68020
pat loc slu $2==4		leaving loc $1 sli 4

pat loc sli ads $1==1 && $2==4 && $3==4
with D_REG4		yields	{regX, 2, %1}
				leaving ads 4

pat loc sli ads $1==2 && $2==4 && $3==4
with D_REG4		yields	{regX, 4, %1}
				leaving ads 4

pat loc sli ads $1==3 && $2==4 && $3==4
with D_REG4		yields	{regX, 8, %1}
				leaving ads 4
#else

pat loc sli $1==1 && $2==WORD_SIZE
with DD_REG
    gen add_i %1, %1    yields  %1

#if WORD_SIZE==2
pat loc sli $1==1 && $2==4
with DD_REG4
    gen add_l %1, %1    yields  %1
#endif

#endif /* TBL68020 */


/************************************************
 * Group 7: increment / decrement / zero	*
 ************************************************/

pat inc					leaving loc 1 adi WORD_SIZE

pat inl inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen add_i {const, 1}, {LOCAL, $1}

pat inl
    kills all_indir, LOCAL %bd==$1
    gen add_i {const, 1}, {LOCAL, $1}

pat lol inl $1==$2
    kills all_indir, LOCAL %bd==$1
    uses DD_REG = {LOCAL, $1}
    gen add_i {const, 1}, {LOCAL, $1}
    killreg %a
			yields %a

pat ine
    kills posextern
    gen add_i {const, 1}, {absolute_int, $1}

pat dec					leaving loc 1 sbi WORD_SIZE

pat del inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen sub_i {const, 1}, {LOCAL, $1}

pat del
    kills all_indir, LOCAL %bd==$1
    gen sub_i {const, 1}, {LOCAL, $1}

pat lol del $1==$2
    kills all_indir, LOCAL %bd==$1
    uses DD_REG = {LOCAL, $1}
    gen sub_i {const, 1}, {LOCAL, $1}
	killreg %a
			yields %a

pat dee
    kills posextern
    gen sub_i {const, 1}, {absolute_int, $1}

pat zrl inreg($1)==reg_any
    kills regvar($1, reg_any), use_index %xreg==regvar($1, reg_any)
    gen clr_i {LOCAL, $1}

pat zrl inreg($1)==reg_pointer
    kills regvar($1, reg_pointer), all_regind %reg==regvar($1, reg_pointer)
    gen move {const4,0}, {areg, regvar($1, reg_pointer)}

pat zrl
    kills all_indir, LOCAL %bd==$1
    gen clr_i {LOCAL, $1}

pat zrl lol $1==$2 && inreg($1) < 0
    kills all_indir, LOCAL %bd==$1
    gen clr_i {LOCAL, $1}	yields {zero_const, 0}

pat zre
    kills posextern
    gen clr_i {absolute_int, $1}

pat zre loe $1==$2
    kills posextern
    gen clr_i {absolute_int, $1}	yields {zero_const, 0}

pat zer $1==4		yields	{zero_const4, 0}
#if WORD_SIZE==2
pat zer $1==6		yields	{zero_const, 0} {zero_const, 0} {zero_const, 0}
#else
pat zer $1==8		yields	{zero_const, 0} {zero_const, 0}
pat zer $1==12		yields	{zero_const, 0} {zero_const, 0} {zero_const, 0}
#endif

pat zer $1/WORD_SIZE <= 65536
with STACK
    uses DD_REG4 = {const, $1/WORD_SIZE -1}
    gen 1:
	clr_i {pre_dec_int, sp}
	dbf %a, {slabel, 1b}

pat zer
with STACK
    uses DD_REG4 = {const, $1/WORD_SIZE}
    gen 1:
	clr_i {pre_dec_int, sp}
	sub_l {const4,1}, %a
	bne {slabel, 1b}

/************************************************
 * Group 8: convert instructions		*
 ************************************************/



pat cii
with STACK
    kills ALL
    gen jsr {absolute4, ".cii"}

#if WORD_SIZE==2
/* No sign-extension, though this is probably not what you may want.
 * This will teach compiler writers not to convert between unsigneds and
 * integers of a different size.
 */
pat loc loc ciu	$1==2 && $2==4
with zero_const
				yields {zero_const4, 0}
with any
uses DD_REG4 = {zero_const4, 0}
    gen move %1,%a.1
    				yields	%a

pat loc loc ciu	$1==4 && $2==2
with zero_const4
				yields {zero_const, 0}
with any4
uses reusing %1, DD_REG4 = %1
    				yields	%a.1

pat loc loc cui	$1==2 && $2==4
with any2
uses DD_REG4={zero_const4,0}
    gen move %1,%a.1			yields %a

pat loc loc cui	$1==4 && $2==2
with DD_REG4
					yields %1.1

pat loc loc cuu $1==2 && $2==4
with any2
uses reusing %1,DD_REG4
    gen move %1,%a.1
	and_l {const4,65535}, %a	yields %a
with any2
uses DD_REG4={zero_const4,0}
    gen move %1,%a.1			yields %a

pat loc loc cuu	$1==4 && $2==2
with DD_REG4
					yields %1.1
#endif

pat cuu
with STACK
    kills ALL
    gen jsr {absolute4, ".cuu"}

pat ciu				leaving cuu

pat cui				leaving cuu

#if TBL68881
pat loc loc cif $1==4 && $2==4
with data4 STACK
    uses FS_REG
    gen	fmove_l %1,%a
	fmove_s %a,{pre_dec4,sp}
pat loc loc cif $1==4 && $2==8
with data4 STACK
    uses FD_REG
    gen	fmove_l %1,%a
	fmove_d %a,{pre_dec4,sp}
pat loc loc cuf $1==4 && $2==4
with D_REG STACK
    uses FS_REG
    gen	fmove_l %1,%a
	tst_l %1
	bge {slabel, 1f}
	fsub_l {const,0-2147483648},%a
	fsub_l {const,0-2147483648},%a
	1:
	fmove_s %a,{pre_dec4,sp}
pat loc loc cuf $1==4 && $2==8
with D_REG STACK
    uses FD_REG
    gen	fmove_l %1,%a
	tst_l %1
	bge {slabel, 1f}
	fsub_l {const,0-2147483648},%a
	fsub_l {const,0-2147483648},%a
	1:
	fmove_d %a,{pre_dec4,sp}
pat loc loc cfi $1==4 && $2==4
with FS_REG
    uses D_REG
    gen	fintrz %1,%1
	fmove_l %1,%a		yields %a
pat loc loc cfi $1==8 && $2==4
with FD_REG
    uses D_REG
    gen	fintrz %1,%1
	fmove_l %1,%a		yields %a
pat loc loc cfu $1==4 && $2==4
with FS_REG
    uses D_REG
    gen fabs %1
	fintrz %1,%1
	fmove_l %1,%a		yields %a
pat loc loc cfu $1==8 && $2==4
with FD_REG
    uses D_REG
    gen fabs %1
	fintrz %1,%1
	fmove_l %1,%a		yields %a
pat loc loc cff $1==4 && $2==8
with FS_REG STACK
    gen fmove_d %1,{pre_dec4,sp}
pat loc loc cff $1==8 && $2==4
with FD_REG STACK
    gen fmove_s %1,{pre_dec4,sp}
#else
/*
 * Floating point stuff
 * Conversion
 */
#if WORD_SIZE==2
/* The patterns need some room on the stack first */
pat loc loc cif	$1==2 && $2==4		leaving loc $1 cal ".cif4"

pat loc loc cif	$1==2 && $2==8
with any2
kills ALL
gen clr_l {pre_dec4, sp}
    move_w %1,{pre_dec2, sp}		leaving loc $1 cal ".cif8"

pat loc loc cif	$1==4 && $2==4		leaving loc $1 cal ".cif4" asp 2

pat loc loc cif	$1==4 && $2==8
with any4
kills ALL
gen clr_w {pre_dec2, sp}
    move_l %1,{pre_dec4, sp}		leaving loc $1 cal ".cif8"

pat loc loc cuf	$1==2 && $2==4		leaving loc $1 cal ".cuf4"

pat loc loc cuf	$1==2 && $2==8
with any2
kills ALL
gen clr_l {pre_dec4, sp}
    move_w %1,{pre_dec2, sp}		leaving loc $1 cal ".cuf8"

pat loc loc cuf	$1==4 && $2==4 leaving loc $1 cal ".cuf4" asp 2

pat loc loc cuf	$1==4 && $2==8
with any4
kills ALL
gen clr_w {pre_dec2, sp}
    move_l %1,{pre_dec4, sp}		leaving loc $1 cal ".cuf8"

pat loc loc cfi	$1==4 && ($2==2 || $2==4)
			leaving loc $1 loc $2 cal ".cfi" asp 8-$2

pat loc loc cfi	$1==8 && ($2==2 || $2==4)
    			leaving loc $1 loc $2 cal ".cfi" asp 12-$2

pat loc loc cfu	$1==4 && ($2==2 || $2==4)
			leaving loc $1 loc $2 cal ".cfu" asp 8-$2
pat loc loc cfu	$1==8 && ($2==2 || $2==4)
    			leaving loc $1 loc $2 cal ".cfu" asp 12-$2
#else
pat loc loc cif	$1==4 && $2==4 leaving loc 4 cal ".cif4" asp 4
pat loc loc cif	$1==4 && $2==8 leaving loc 4 cal ".cif8"
pat loc loc cuf	$1==4 && $2==4 leaving loc 4 cal ".cuf4" asp 4
pat loc loc cuf	$1==4 && $2==8 leaving loc 4 cal ".cuf8"
pat loc loc cfi	leaving loc $1 loc $2 cal ".cfi" asp $1+4
pat loc loc cfu	leaving loc $1 loc $2 cal ".cfu" asp $1+4
#endif
pat loc loc cff	$1==8 && $2==4 leaving cal ".cff4" asp 4
pat loc loc cff	$1==4 && $2==8
	leaving zer 4 exg 4 cal ".cff8"
#endif	/* TBL68881 */

/************************************************
 * Group 9: logical instructions		*
 ************************************************/


#if WORD_SIZE==2
proc log2w
with datalt4+consts4-sconsts4 DD_REG4
    gen xxx* %1, %2	yields	%2
with DD_REG4 datalt4+consts4-sconsts4
    gen xxx* %2, %1	yields	%1
with exact any4 STACK
    uses reusing %1,DD_REG4=%1
    gen xxx* {post_inc4, sp}, %a	yields %a
#endif

proc logw
with datalt_int+consts-sconsts DD_REG
    gen xxx* %1, %2	yields	%2
with DD_REG datalt_int+consts-sconsts
    gen xxx* %2, %1	yields	%1
with exact any_int STACK
    uses reusing %1,DD_REG=%1
    gen xxx* {post_inc_int, sp}, %a	yields %a

proc logdef example and
with STACK
    uses DD_REG4 = {const, $1/WORD_SIZE -1},
	 AA_REG,
	 DD_REG
    gen 
	lea {regAcon, sp, $1}, %b
	1:
	move_i {post_inc_int, sp}, %c
	xxx* %c, {post_inc_int, %b}
	dbf %a, {slabel, 1b}

#if WORD_SIZE==4
proc logndef
with DD_REG4 STACK
    uses AA_REG,
	 DD_REG
    gen
	lea {regAregXcon, sp, %1, 1, 0},%a
	asr_l {small_const, 2}, %1
	1:
	move_i {post_inc_int, sp}, %b
	xxx* %b, {post_inc_int, %a}
	sub_l {const4,1}, %1
	bne {slabel, 1b}
#else
proc logndef
with any_int STACK
    uses AA_REG,
	 DD_REG,
	 DD_REG4={const,0}
    gen
	move %1, %c.1
	lea {regAregXcon, sp, %c, 1, 0},%a
	asr_l {small_const, 1}, %c
	sub_l {const4,1}, %c
	1:
	move_i {post_inc_int, sp}, %b
	xxx* %b, {post_inc_int, %a}
	dbf %c, {slabel, 1b}
#endif

proc logbdef example and
with STACK
    uses AA_REG,
	 DD_REG,
	 DD_REG4
    gen
	move_l {const4,$1/WORD_SIZE}, %c
	lea {regAregXcon, sp, %c, 1, 0},%a
	1:
	move_i {post_inc_int, sp}, %b
	xxx* %b, {post_inc_int, %a}
	sub_l {const4,1}, %c
	bne {slabel, 1b}

pat and $1==WORD_SIZE			call logw(AND_I)
#if WORD_SIZE==2
pat and $1==2*WORD_SIZE			call log2w("and.l")
#endif
pat and $1>4 && $1/WORD_SIZE<=65536	call logdef(AND_I)
pat and defined($1)			call logbdef(AND_I)
pat and !defined($1)			call logndef(AND_I)

pat ior $1==WORD_SIZE			call logw(OR_I)
#if WORD_SIZE==2
pat ior $1==2*WORD_SIZE			call log2w("or.l")
#endif
pat ior $1>2 && $1/WORD_SIZE<=65536	call logdef(OR_I)
pat ior defined($1)			call logbdef(OR_I)
pat ior !defined($1)			call logndef(OR_I)

#if WORD_SIZE==2
pat xor $1==2
with DD_REG conreg2-bconst
    gen eor_w %2, %1	yields	%1
#endif

pat xor $1==4
with DD_REG4 conreg4-bconst4
    gen eor_l %2, %1	yields	%1

pat xor $1>4 && $1/WORD_SIZE<=65536		call logdef(EOR_I)
pat xor defined($1)			call logbdef(EOR_I)
pat xor !defined($1)			call logndef(EOR_I)

#if WORD_SIZE==2
pat com $1==2
with DD_REG
    gen not_w %1	yields	%1
#endif

pat com $1==4
with DD_REG4
    gen not_l %1	yields	%1

pat com $1==8
with DD_REG4 DD_REG4
    gen not_l %1
	not_l %2	yields	%2 %1

pat com $1>8 && $1/WORD_SIZE<=65536
with STACK
    uses AA_REG,
	 DD_REG4 = {const, $1/WORD_SIZE -1}
    gen move_l sp, %a
	1:
	not_i {post_inc_int, %a}
	dbf %b, {slabel, 1b}

pat com defined($1)
with STACK
    uses AA_REG,
	 DD_REG4 = {const, $1/WORD_SIZE}
    gen	move_l sp, %a
	1:
	not_i {post_inc_int, %a}
	sub_l {const4, 1}, %b
	bne {slabel, 1b}

#if WORD_SIZE==4
pat com !defined($1)
with DD_REG STACK
    uses AA_REG
    gen move_l sp, %a
	asr_l {small_const, 2}, %1
	1:
	not_i {post_inc_int, %a}
	sub_l {const4, 1}, %1
	bne {slabel, 1b}
#else
pat com !defined($1)
with any_int STACK
    uses AA_REG,
	 DD_REG4={const,0}
    gen move %1, %b.1
	move_l sp, %a
	asr_l {small_const, 1}, %b
	sub_l {const4, 1}, %b
	1:
	not_i {post_inc_int, %a}
	dbf %b, {slabel, 1b}
#endif

#if WORD_SIZE==2
pat rol $1==2
with shconreg DD_REG
    gen rol_w %1, %2	yields	%2
#endif

pat rol $1==4
with shconreg DD_REG4
    gen rol_l %1, %2	yields	%2

#if WORD_SIZE==2
pat ror $1==2
with shconreg DD_REG
    gen ror_w %1, %2	yields	%2
#endif

pat ror $1==4
with shconreg DD_REG4
    gen ror_l %1, %2	yields	%2

	


/************************************************
 * Group 10: sets				*
 ************************************************/

#if WORD_SIZE==2
pat inn $1==4
with conreg2 DD_REG4
    gen btst %1, %2.1
	sne {dreg1, %2.1}
	and_l {const4, 1}, %2
			yields	%2.1
#endif

pat inn $1==WORD_SIZE
with conreg2 DD_REG
    gen btst %1, %2
	sne {dreg1, %2}
	and_i {const, 1}, %2
			yields	%2

/* The interface for the .inn differ for m68k2 and m68k4. */
/* ??? Work out a cleaner interface, that is similar for all tables */
#if WORD_SIZE==2
pat inn defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".inn"}
	killreg d0
			yields	d0

pat inn !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".inn"}
	killreg d0
			yields	d0
#else
pat inn defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	move {const, $1}, d1
	jsr {absolute4, ".inn"}
	killreg d0
			yields	d0

pat inn !defined($1)
with any_int any_int STACK
    kills ALL
    gen move %2, d0
	move %1, d1
	jsr {absolute4, ".inn"}
	killreg d0
			yields	d0
#endif /* WORD_SIZE==2 */

pat loc inn $2==WORD_SIZE && small($1)
with DD_REG
    gen asr_i {small_const, $1}, %1
	and_i {const, 1}, %1
			yields	%1

#if WORD_SIZE==2
pat set $1==2
with conreg2
    uses DD_REG = {zero_const, 0}
    gen bset %1, %a	yields	%a
#endif

pat set $1==4
with conreg2
    uses DD_REG4 = {zero_const4, 0}
    gen bset %1, %a	yields	%a

#if WORD_SIZE==2
pat set $1>4
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".set"}

pat set !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".set"}
#else
pat set $1>4
with any_int STACK
    kills ALL
    gen move %1, d0
	move {const, $1}, d1
	jsr {absolute4, ".set"}

pat set !defined($1)
with any_int any_int STACK
    kills ALL
    gen move %2, d0
	move %1, d1
	jsr {absolute4, ".set"}
#endif /* WORD_SIZE==2 */




/************************************************
 * Group 11: arrays				*
 ************************************************/

/* ??? interface */
#if WORD_SIZE==2
pat lar defined($1) && $1 == WORD_SIZE
with STACK
    kills ALL
    gen jsr {absolute4, ".lar"}

pat sar defined($1) && $1 == WORD_SIZE
with STACK
    kills ALL
    gen jsr {absolute4, ".sar"}

pat aar defined($1) && $1 == WORD_SIZE
with STACK
    kills ALL
    gen jsr {absolute4, ".aar"}
#else
pat lar defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".lar"}

pat lar !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".lar"}

pat sar defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".sar"}

pat sar !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".sar"}

pat aar defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".aar"}
			yields	a0

pat aar !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".aar"}
			yields	a0

#if ARR_OPT
pat lae lar $2==4 && nicesize(rom($1,3))
				leaving lae $1 aar 4 loi rom($1, 3)
pat lae sar $2==4 && nicesize(rom($1,3))
				leaving lae $1 aar 4 sti rom($1, 3)

pat lae aar $2==4 && rom($1,3)==1
				leaving ads 4 adp 0-rom($1,1)

#ifdef TBL68020
pat lae aar $2==4 && nicesize(rom($1,3))
with D_REG		yields	{regX, rom($1,3), %1}
				leaving ads 4 adp rom($1,3)*(0-rom($1,1))
#else /* TBL68020 */
pat lae aar $2==4 && rom($1,3)==2
with DD_REG
    gen asl_l {small_const, 1}, %1
			yields	%1
				leaving ads 4 adp (0 - rom($1,1))<<1

pat lae aar $2==4 && rom($1,3)==4
with DD_REG
    gen asl_l {small_const, 2}, %1
			yields	%1
				leaving ads 4 adp (0 - rom($1,1))<<2

pat lae aar $2==4 && rom($1,3)==8
with DD_REG
    gen asl_l {small_const, 3}, %1
			yields	%1
				leaving ads 4 adp (0 - rom($1,1))<<3
#endif /* TBL68020 */
#endif	/* ARR_OPT */
#endif /* WORD_SIZE!=2 */

	/* I WOULD ALSO LIKE THESE:
	 * pat lae aar $2==4 && defined(rom($1,3))
	 * with const 		leaving adp rom($1,3)*(%1.num-rom($1,1))
	 * pat lae lar $2==4 && defined(rom($1,3))
	 * with const		leaving adp rom($1,3)*(%1.num-rom($1,1))
	 *				loi rom($1,3)
	 * pat lae sar $2==4 && defined(rom($1,3))
	 * with const		leaving adp rom($1,3)*(%1.num-rom($1,1))
	 *				sti rom($1,3)
	 * BUT THEY DON'T WORK.
	 */



/************************************************
 * Group 12: compare instructions		*
 ************************************************/


#if WORD_SIZE==2
pat cmi defined($1) && $1==2
with any2 DD_REG
    uses DD_REG = {zero_const, 0}
    gen cmp_w %1,%2
	beq {slabel,2f}
	bgt {slabel,1f}
	add_w {small_const, 1},%a
	bra {slabel,2f}
	1:
	sub_w {small_const, 1},%a
	2:
					yields %a

pat cmi defined($1) && $1==4
with STACK
	gen jsr {absolute4, ".cmi"}	yields d1
#else
/* pat cmi $1==4			leaving sbi 4
   WRONG !!
*/

pat cmi defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".cmi"}
			yields	d0

pat cmi !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".cmi"}
			yields	d0
#endif

/* pat cmu $1==4			leaving sbi 4
   WRONG !!
*/

#if WORD_SIZE==2
pat cmu defined($1)
with STACK
    gen move {const, $1},d0
	jsr {absolute4, ".cmu"}

pat cmu !defined($1)
with any STACK
    gen move %1,d0
	jsr {absolute4, ".cmu"}
#else
pat cmu defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".cmu"}
			yields	d0

pat cmu !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".cmu"}
			yields	d0
#endif /* WORD_SIZE==2 */

#if WORD_SIZE==2
pat cms $1==2			leaving cmi 2
pat cms $1==4			leaving cmi 4
#else
pat cms $1==4			leaving cmi 4
#endif

pat cms defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".cms"}
			yields	d0

pat cms !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".cms"}
			yields	d0

pat cmp				leaving cmu 4

#ifndef XXXXX
proc txx
with test_set_int
    uses reusing %1,DD_REG
    gen test %1
	bxx[1] {slabel,1f}
	clr_i %a
	bra {slabel,2f}
	1:
	move_i {small_const,1},%a
	2:
			yields	%a
#if WORD_SIZE==2
with test_set1
#else
with test_set1 + test_set2
#endif
    uses reusing %1,DD_REG
    gen test %1
	bxx[2] {slabel,1f}
	clr_i %a
	bra {slabel,2f}
	1:
	move_i {small_const,1},%a
	2:
			yields	%a

/* for some branches, we need to get rid of the overflow bit first.
   The easiest way to do this is to just test ....
*/
proc txx_ouch
with test_set_int
    uses reusing %1,DD_REG
    gen	killcc.
	test %1
	bxx[1] {slabel,1f}
	clr_i %a
	bra {slabel,2f}
	1:
	move_i {small_const,1},%a
	2:
			yields	%a
#if WORD_SIZE==2
with test_set1
#else
with test_set1 + test_set2
#endif
    uses reusing %1,DD_REG
    gen test %1
	bxx[2] {slabel,1f}
	clr_i %a
	bra {slabel,2f}
	1:
	move_i {small_const,1},%a
	2:
			yields	%a

pat tlt					call txx("bmi", "bcs")
pat tle					call txx_ouch("ble", "bls")
pat teq					call txx("beq", "beq")
pat tne					call txx("bne", "bne")
pat tge					call txx("bpl", "bcc")
pat tgt					call txx_ouch("bgt", "bhi")
#else
proc txx
with test_set_int
    uses reusing %1,DD_REG
    gen test %1
	sxx[1] %a
	neg_b %a
			yields {extend1, %a}

#if WORD_SIZE==2
with test_set1
#else
with test_set1 + test_set2
#endif
    uses reusing %1,DD_REG
    gen test %1
	sxx[2] %a
	neg_b %a
			yields {extend1, %a}

pat tlt					call txx("smi", "scs")
pat tle					call txx("sle", "sls")
pat teq					call txx("seq", "seq")
pat tne					call txx("sne", "sne")
pat tge					call txx("spl", "scc")
pat tgt					call txx("sgt", "shi")
#endif

/*
 * Floating point
 * Comparision
 */
#if TBL68881
pat cmf $1==4
with FS_REG FS_REG
    uses D_REG={const,0}
    gen	fcmp %1,%2
	fbeq {slabel,2f}
	fblt {slabel,1f}
	add_l {const,1},%a
	bra {slabel,2f}
	1:
	sub_l {const,1},%a
	2:			yields %a
pat cmf $1==8
with FD_REG FD_REG
    uses D_REG={const,0}
    gen	fcmp %1,%2
	fbeq {slabel,2f}
	fblt {slabel,1f}
	add_l {const,1},%a
	bra {slabel,2f}
	1:
	sub_l {const,1},%a
	2:			yields %a
#else
pat cmf $1==4	leaving cal ".cmf4" asp 8 lfr WORD_SIZE
pat cmf $1==8	leaving cal ".cmf8" asp 16 lfr WORD_SIZE
#endif
/*
 * Floating Point
 * Zero Constants
 */
pat zrf		leaving zer $1

/************************************************
 * Group 13: branch instructions		*
 ************************************************/

#if WORD_SIZE==2
pat lab topeltsize($1)==4 && !fallthrough($1)
kills ALL
gen labeldef $1			yields dl0

pat lab topeltsize($1)==4 && fallthrough($1)
with any4 STACK
kills ALL
gen move %1, dl0
    killreg dl0
    labeldef $1			yields dl0
#endif

pat lab topeltsize($1)==WORD_SIZE && !fallthrough($1)
kills ALL
gen labeldef $1			yields d0

pat lab topeltsize($1)==WORD_SIZE && fallthrough($1)
with any_int STACK
kills ALL
gen move %1,d0
    killreg d0
    labeldef $1			yields d0

pat lab
with STACK
kills ALL
gen labeldef $1

#if WORD_SIZE==2
pat bra topeltsize($1)==4
with any4 STACK
gen move %1,dl0
    bra {llabel, $1}
#endif

pat bra	topeltsize($1)==WORD_SIZE
with any_int STACK
gen move %1,d0
    bra {llabel, $1}

pat bra
with STACK
    gen bra {llabel, $1}

proc brxx example beq
with exact extend1 extend1
    kills ALL
    gen cmp_b %1,%2
	bxx[1] {llabel, $1}
#if WORD_SIZE!=2
with exact extend2 extend2
    kills ALL
    gen cmp_w %1,%2
	bxx[1] {llabel, $1}
#endif
with exact sconsts any_int
    kills ALL
    uses DD_REG=%1
    gen cmp_i %2, %a
	bxx[2] {llabel, $1}
with exact any_int sconsts
    kills ALL
    uses DD_REG=%2
    gen cmp_i %1, %a
	bxx[1] {llabel, $1}
with any_int-sconsts genreg STACK
    gen cmp_i %1, %2
	bxx[1] {llabel, $1}
with genreg any_int-sconsts STACK
    gen cmp_i %2, %1
	bxx[2] {llabel, $1}
with exact immediate_int-sconsts imm_cmp_int
    kills ALL
    gen cmp_i %1, %2
	bxx[1] {llabel, $1}
with exact imm_cmp_int immediate_int-sconsts
    kills ALL
    gen cmp_i %2, %1
	bxx[2] {llabel, $1}
with exact immediate_int-sconsts STACK
    gen cmp_i %1, {post_inc_int, sp}
	bxx[1] {llabel, $1}
with exact any_int STACK
    uses reusing %1,DD_REG=%1
    gen cmp_i {post_inc_int, sp}, %a
	bxx[2] {llabel, $1}
with exact STACK
    uses DD_REG
    gen	move_i {post_inc_int, sp},%a
	cmp_i {post_inc_int, sp},%a
	bxx[2] {llabel, $1}
#if WORD_SIZE==4
with exact post_inc4 post_inc4
    gen cmp_l %1,%2
	bxx[1] {llabel, $1}
#endif
with exact post_inc2 post_inc2
    gen cmp_w %1,%2
	bxx[1] {llabel, $1}
with exact post_inc1 post_inc1
    gen cmp_b %1,%2
	bxx[1] {llabel, $1}

pat blt					call brxx("blt","bgt")
pat ble					call brxx("ble","bge")
pat beq					call brxx("beq","beq")
pat bne					call brxx("bne","bne")
pat bge					call brxx("bge","ble")
pat bgt					call brxx("bgt","blt")

proc zxx example zeq
with test_set_int STACK
    gen test %1
	bxx[1] {llabel, $1}
#if WORD_SIZE==2
with test_set1 STACK
#else
with test_set1 + test_set2 STACK
#endif
    gen test %1
	bxx[2] {llabel, $1}
with exact STACK
    gen tst_i {post_inc_int, sp}
	bxx[1] {llabel, $1}

/* for some branches, we need to get rid of the overflow bit first.
   The easiest way to do this is to just test ....
*/
proc zxx_ouch example zeq
with test_set_int STACK
    gen killcc.
	test %1
	bxx[1] {llabel, $1}
#if WORD_SIZE==2
with test_set1 STACK
#else
with test_set1 + test_set2 STACK
#endif
    gen test %1
	bxx[2] {llabel, $1}
with exact STACK
    gen tst_i {post_inc_int, sp}
	bxx[1] {llabel, $1}

pat zlt					call zxx("bmi", "bcs")
pat zle					call zxx_ouch("ble", "bls")
pat zeq					call zxx("beq", "beq")
pat zne					call zxx("bne", "bne")
pat zge					call zxx("bpl", "bcc")
pat zgt					call zxx_ouch("bgt", "bhi")

/************************************************
 * Group 14: procedure calls instructions	*
 ************************************************/


pat cai
with exact ext_addr
    kills ALL
    gen jsr {absolute4, %1.bd}
with A_REG STACK
    kills ALL
    gen jsr {indirect4, %1}
with STACK
    kills ALL
    uses AA_REG = {post_inc4, sp}
    gen jsr {indirect4, %a}
with address STACK
    kills ALL
    gen jsr %1

pat cal
with STACK
    kills ALL
    gen jsr {absolute4, $1}

#if WORD_SIZE==2
pat lfr $1==2		yields	d0
pat lfr $1==4		yields	dl0
pat lfr $1==8		yields	dl1 dl0
#else
pat lfr $1==4		yields	d0
pat lfr $1==8		yields	d1 d0
#endif

pat ret $1==0
    gen return

pat asp ret $2==0
    gen return

#if WORD_SIZE==2
pat ret $1==2
with any2
    gen move %1, d0
	return
with exact STACK
    gen move_w {post_inc2, sp}, d0
	return
#endif

pat ret $1==4
with any4
    gen move %1, dl0
	return
with exact STACK
    gen move_l {post_inc4, sp}, dl0
	return

pat ret $1==8
with any4 any4
    gen move %1, dl0
	move %2, dl1
	return
with exact any4 STACK
    gen move %1, dl0
	move_l {post_inc4, sp}, dl1
	return
with exact STACK
    gen move_l {post_inc4, sp}, dl0
	move_l {post_inc4, sp}, dl1
	return


/************************************************
 * Group 15: miscellaneous instructions		*
 ************************************************/

#if WORD_SIZE==2
pat asp $1==2
with any2-pre_post
with STACK
    gen add_l {const4, $1}, sp
#endif

pat asp $1==4
#if WORD_SIZE==2
with any-pre_post any-pre_post
#endif
with any4-pre_post
with STACK
    gen add_l {const4, $1}, sp

#if WORD_SIZE==2
pat asp $1==6
with any4-pre_post any-pre_post
with any-pre_post any4-pre_post
with any-pre_post any-pre_post any-pre_post
with STACK
    gen add_l {const4, $1}, sp
#endif

pat asp $1==8
with any4-pre_post any4-pre_post
with STACK
    gen add_l {const4, $1}, sp

pat asp
with STACK
    gen lea {regAcon, sp, $1}, sp

/* ??? DD_REG$ ??? */
#if WORD_SIZE==2
pat ass $1==2
with any2 STACK
uses reusing %1,DD_REG4
    gen move %1,%a.1
	ext_l %a.1
	add_l %a, sp
#endif

pat ass $1==4
with any4 STACK
    gen add_l %1, sp

#if WORD_SIZE==2
pat blm $1==2
with A_REG A_REG
    kills allexceptcon
    gen move_w {indirect2, %2}, {indirect2, %1}
#endif

pat blm $1==4
with A_REG A_REG
    kills allexceptcon
    gen move_l {indirect4, %2}, {indirect4, %1}

#if WORD_SIZE==2
pat blm $1==6
with A_REG A_REG
    kills allexceptcon
    gen move_l {indirect4, %2}, {indirect4, %1}
	move_w {offsetted2, %2, 4}, {offsetted2, %1, 4}
#endif

pat blm $1==8
with A_REG A_REG
    kills allexceptcon
    gen	move_l {indirect4, %2}, {indirect4, %1}
	move_l {offsetted4, %2, 4}, {offsetted4, %1, 4}

pat blm $1>2*WORD_SIZE && $1/WORD_SIZE <= 65536
with AA_REG AA_REG
    kills ALL
    uses DD_REG4={const, $1/WORD_SIZE -1}
    gen 1:
	move_i {post_inc_int, %2}, {post_inc_int, %1}
	dbf %a, {slabel, 1b}

pat blm
with AA_REG AA_REG
    kills ALL
    uses DD_REG4={const,$1/WORD_SIZE}
    gen	1:
	move_i {post_inc_int, %2}, {post_inc_int, %1}
	sub_l {const4, 1}, %a
	bne {slabel, 1b}

#if WORD_SIZE==2
pat bls $1==2
with DD_REG AA_REG AA_REG
    kills ALL
    gen asr_w {small_const, 1}, %1
	beq {slabel, 2f}
	1:
	move_w {post_inc2, %3}, {post_inc2, %2}
	sub_w {const, 1}, %1
	bne {slabel, 1b}
	2:
#endif

pat bls $1==4
with DD_REG4 AA_REG AA_REG
    kills ALL
    gen
#if WORD_SIZE==2
	asr_l {small_const, 1}, %1
#else
	asr_l {small_const, 2}, %1
#endif
	beq {slabel, 2f}
	1:
	move_i {post_inc_int, %3}, {post_inc_int, %2}
	sub_l {const4, 1}, %1
	bne {slabel, 1b}
	2:

#if WORD_SIZE==2
pat csa $1==2
#if TBL68020
with any4 D_REG+LOCAL+const+ILOCAL+absolute2 STACK
#else
with any4 D_REG+LOCAL+const+absolute2 STACK
#endif
    gen move %1,a0
	move %2,d0
	jmp {absolute4, ".csa2"}
#endif

pat csa $1==4
#if TBL68020 && WORD_SIZE==4
with any4 D_REG4+DLOCAL+const4+ILOCAL+absolute4 STACK
#else
with any4 D_REG4+DLOCAL+const4+absolute4 STACK
#endif
    gen move %1,a0
	move %2,dl0
	jmp {absolute4, ".csa4"}

#if WORD_SIZE==2
pat csb $1==2
#if TBL68020
with any4 D_REG+LOCAL+const+ILOCAL+absolute2 STACK
#else
with any4 D_REG+LOCAL+const+absolute2 STACK
#endif
    gen move %1,a0
	move %2,d0
	jmp {absolute4, ".csb2"}
#endif

pat csb $1==4
#if TBL68020 && WORD_SIZE==4
with any4 D_REG4+DLOCAL+const4+ILOCAL+absolute4 STACK
#else
with any4 D_REG4+DLOCAL+const4+absolute4 STACK
#endif
    gen move %1,a0
	move %2,dl0
	jmp {absolute4, ".csb4"}

pat dch				leaving loi 4

#if WORD_SIZE==2
pat dup $1==2
with dups2				yields	%1 %1
#endif

pat dup $1==4
#if WORD_SIZE==2
with dups2 dups2			yields	%2 %1 %2 %1
#endif
with dups4				yields	%1 %1

pat dup $1==8
with dups4 dups4			yields	%2 %1 %2 %1

pat dup $1>2*WORD_SIZE && $1/WORD_SIZE<=65536
with STACK
    uses DD_REG4 = {const, $1/WORD_SIZE -1}
    gen 1:
	move_i {offsetted_int, sp, $1 -WORD_SIZE}, {pre_dec_int, sp}
	dbf %a, {slabel, 1b}

pat dup
with STACK
    uses DD_REG4 = {const, $1/WORD_SIZE}
    gen 1:
	move_i {offsetted_int, sp, $1 -WORD_SIZE}, {pre_dec_int, sp}
	sub_l {const4, 1}, %a
	bne {slabel, 1b}

#if WORD_SIZE==2
pat dus $1==2
with any2 STACK
    uses DD_REG4 = {zero_const4, 0}, AA_REG
    gen
	move_w %1, %a.1
	lea {regAregXcon, sp, %a, 1, 0}, %b
	asr_l {small_const, 1}, %a
	beq {slabel, 2f}
	1:
	move_w {pre_dec2, %b}, {pre_dec2, sp}
	sub_l {const4, 1}, %a
	bne {slabel, 1b}
	2:
#endif

pat dus $1==4
with DD_REG4 STACK
    uses AA_REG
    gen
    	lea {regAregXcon, sp, %1, 1, 0}, %a
#if WORD_SIZE==2
	asr_l {small_const, 1}, %1
#else
	asr_l {small_const, 2}, %1
#endif
	beq {slabel, 2f}
	1:
	move_i {pre_dec_int, %a}, {pre_dec_int, sp}
	sub_l {const4, 1}, %1
	bne {slabel, 1b}
	2:

#if WORD_SIZE==2
pat exg $1==2
with any2 any2		yields	%1 %2
#endif

pat exg $1==4
with any4 any4		yields	%1 %2

pat exg defined($1)
with STACK
    kills ALL
    gen move {const, $1}, d0
	jsr {absolute4, ".exg"}

pat exg !defined($1)
with any_int STACK
    kills ALL
    gen move %1, d0
	jsr {absolute4, ".exg"}

pat fil
    gen move_l {ext_addr, $1}, {absolute4, ".filn"}

pat gto
with STACK
    uses AA_REG = {ext_addr, $1}
    gen move_l {offsetted4, %a, 8}, lb
	move_l {offsetted4, %a, 4}, sp
#if TBL68020 && FANCY_MODES
	jmp {OFF_off4, %a, 0, 0}
#else
	move_l {indirect4, %a}, %a
	jmp {indirect4, %a}
#endif

pat lim			yields	{absolute_int, ".trpim"}

pat lin
    kills posextern
    gen move_i {const, $1}, {absolute_int, ".lino"}
    
pat lni
    kills posextern
    gen add_i {const, 1}, {absolute_int, ".lino"}

pat lor $1==0		yields	lb

pat lor $1==1
with STACK
    uses AA_REG = sp	yields	%a

pat lor $1==2		yields	{absolute4, ".reghp"}

pat lpb				leaving adp 8

pat mon
with STACK
    kills ALL
    gen jsr {absolute4, ".mon"}

pat nop
with STACK
    kills ALL
#ifdef DEBUG
    gen jsr {absolute4, ".nop"}
#endif

#if WORD_SIZE==2
pat rck $1==2
#ifdef TBL68020
with ext_addr D_REG
    gen cmp2_w {absolute2, %1.bd}, %2
	bcc {slabel, 1f}
	move_w {small_const, 1}, {pre_dec2, sp}	/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
with address-ext_addr D_REG
    gen cmp2_w %1, %2
	bcc {slabel, 1f}
	move_w {small_const, 1}, {pre_dec2, sp}	/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
with A_REG D_REG
    gen cmp2_w {indirect2, %1}, %2
	bcc {slabel, 1f}
	move_w {small_const, 1}, {pre_dec2, sp}	/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
#else
with STACK
    kills ALL
    gen jsr {absolute4, ".rck"}
#endif
#endif	/* WORD_SIZE==2 */

#if WORD_SIZE==4 || TBL68020
pat rck $1==4
#ifdef TBL68020
with ext_addr D_REG4
    gen cmp2_l {absolute4, %1.bd}, %2
	bcc {slabel, 1f}
	pea {absolute4, 1}			/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
with address-ext_addr D_REG4
    gen cmp2_l %1, %2
	bcc {slabel, 1f}
	pea {absolute4, 1}			/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
with A_REG D_REG4
    gen cmp2_l {indirect4, %1}, %2
	bcc {slabel, 1f}
	pea {absolute4, 1}			/* push constant 1 == ERANGE */
	jsr {absolute4, ".trp"}
	1:			yields	%2
#else /* TBL68020 */
with STACK
    kills ALL
    gen jsr {absolute4, ".rck"}
#endif /* TBL68020 */
#endif /* WORD_SIZE==4 || TBL68020 */

pat rtt				leaving ret 0

pat sig
with any4
    kills posextern
    uses AA_REG
    gen move_l {absolute4, ".trppc"}, %a
	move_l %1, {absolute4, ".trppc"}
			yields	%a

pat sim
with any_int
    kills posextern
    gen move_i %1, {absolute_int, ".trpim"}

pat str $1==0
with any4 STACK
    kills ALL
    gen move_l %1, lb

pat str $1==1
with any4 STACK
    gen move_l %1, sp

pat str $1==2
with STACK
    kills ALL
    gen jsr {absolute4, ".strhp"}

pat trp
with STACK
    kills ALL
    gen jsr {absolute4, ".trp"}
 


/************************************************
 * more rules for long EM-patterns		*
 ************************************************/

pat loe ine $1==$2
    kills posextern
    uses DD_REG = {absolute_int, $1}
    gen add_i {const,1}, {absolute_int, $1}
    killreg %a
			yields	%a

pat loe dee $1==$2
    kills posextern
    uses DD_REG = {absolute_int, $1}
    gen sub_i {const,1}, {absolute_int, $1}
    killreg %a
			yields	%a


proc llol1shstl example lol loc sli stl		/* only left */
    kills all_indir, DLOCAL %bd==$1
    gen shw* {offsetted2, lb, $1+2}
	roxl {offsetted2, lb, $1}

proc lloe1shste example loe loc sli ste		/* only left */
    kills posextern
    gen shw* {absolute2, $1+2}
	roxl {absolute2, $1}

proc llil1shsil example lil loc sli sil		/* only left */
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen shw* {OFF_off2, lb, $1, 2}
	roxl {OFF_off2, lb, $1, 0}
#else
    uses AA_REG = {DLOCAL, $1}
    gen shw* {offsetted2, %a, 2}
	roxl {indirect2, %a}
#endif

proc rlol1shstl example lol loc sri stl		/* only right */
    kills all_indir, DLOCAL %bd==$1
    gen shw* {offsetted2, lb, $1}
	roxr {offsetted2, lb, $1+2}

proc rloe1shste example loe loc sri ste		/* only right */
    kills posextern
    gen shw* {absolute2, $1}
	roxr {absolute2, $1+2}

proc rlil1shsil example lil loc sri sil		/* only right */
    kills allexceptcon
#if TBL68020 && FANCY_MODES
    gen shw* {OFF_off2, lb, $1, 0}
	roxr {OFF_off2, lb, $1, 2}
#else
    uses AA_REG = {DLOCAL, $1}
    gen shw* {indirect2, %a}
	roxr {offsetted2, %a, 2}
#endif

pat lol loc sli stl $1==$4 && $2==1 && $3==4	call llol1shstl("asl #1,")
pat loe loc sli ste $1==$4 && $2==1 && $3==4	call lloe1shste("asl #1,")
pat lil loc sli sil $1==$4 && $2==1 && $3==4	call llil1shsil("asl #1,")
pat lol loc sri stl $1==$4 && $2==1 && $3==4	call rlol1shstl("asr #1,")
pat loe loc sri ste $1==$4 && $2==1 && $3==4	call rloe1shste("asr #1,")
pat lil loc sri sil $1==$4 && $2==1 && $3==4	call rlil1shsil("asr #1,")
pat lol loc slu stl $1==$4 && $2==1 && $3==4	call llol1shstl("asl #1,")
pat loe loc slu ste $1==$4 && $2==1 && $3==4	call lloe1shste("asl #1,")
pat lil loc slu sil $1==$4 && $2==1 && $3==4	call llil1shsil("asl #1,")
pat lol loc sru stl $1==$4 && $2==1 && $3==4	call rlol1shstl("lsr #1,")
pat loe loc sru ste $1==$4 && $2==1 && $3==4	call rloe1shste("lsr #1,")
pat lil loc sru sil $1==$4 && $2==1 && $3==4	call rlil1shsil("lsr #1,")


proc txxand
with test_set_int DD_REG
    gen test %1
	bxx[1] {slabel, 1f}
	bclr {const,0}, %2
	1:		yields	%2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
    gen test %1
	bxx[2] {slabel, 1f}
	bclr {const,0}, %2
	1:		yields	%2

proc txxior
with test_set_int DD_REG
    gen test %1
	bxx[1] {slabel, 1f}
	bset {zero_const, 0}, %2
	1:		yields	%2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
    gen test %1
	bxx[2] {slabel, 1f}
	bset {zero_const, 0}, %2
	1:		yields	%2

proc txxand_ouch
with test_set_int DD_REG
    gen	killcc.
	test %1
	bxx[1] {slabel, 1f}
	bclr {const,0}, %2
	1:		yields	%2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
    gen test %1
	bxx[2] {slabel, 1f}
	bclr {const,0}, %2
	1:		yields	%2

proc txxior_ouch
with test_set_int DD_REG
    gen	killcc.
	test %1
	bxx[1] {slabel, 1f}
	bset {zero_const, 0}, %2
	1:		yields	%2
#if WORD_SIZE==2
with test_set1 DD_REG
#else
with test_set1 + test_set2 DD_REG
#endif
    gen test %1
	bxx[2] {slabel, 1f}
	bset {zero_const, 0}, %2
	1:		yields	%2

pat tlt and $2==WORD_SIZE		call txxand("bmi", "bcs")
pat tle and $2==WORD_SIZE		call txxand_ouch("ble", "bls")
pat teq and $2==WORD_SIZE		call txxand("beq", "beq")
pat tne and $2==WORD_SIZE		call txxand("bne", "bne")
pat tge and $2==WORD_SIZE		call txxand("bpl", "bcc")
pat tgt and $2==WORD_SIZE		call txxand_ouch("bgt", "bhi")

pat tlt ior $2==WORD_SIZE		call txxior("bpl", "bcc")
pat tle ior $2==WORD_SIZE		call txxior_ouch("bgt", "bhi")
pat teq ior $2==WORD_SIZE		call txxior("bne", "bne")
pat tne ior $2==WORD_SIZE		call txxior("beq", "beq")
pat tge ior $2==WORD_SIZE		call txxior("bmi", "bcs")
pat tgt ior $2==WORD_SIZE		call txxior_ouch("ble", "bls")

proc cmxtxxand
with exact extend1 extend1 DD_REG
    gen cmp_b %2, %1
	bxx[2] {llabel,1f}
	bclr {const,0}, %3
	1:		yields	%3
with exact extend2 extend2 DD_REG
    gen cmp_w %2, %1
	bxx[2] {llabel,1f}
	bclr {const,0}, %3
	1:		yields	%3
with exact sconsts any_int DD_REG
    uses DD_REG=%1
    gen cmp_i %2, %a
	bxx[2] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3
with exact any_int sconsts DD_REG
    uses DD_REG=%2
    gen cmp_i %1, %a
	bxx[1] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3
with any_int-sconsts genreg DD_REG
    gen cmp_i %1, %2
	bxx[1] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3
with genreg any_int-sconsts DD_REG
    gen cmp_i %2, %1
	bxx[2] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3
with exact immediate_int-sconsts imm_cmp_int DD_REG
    gen cmp_i %1, %2
	bxx[1] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3
with exact imm_cmp_int immediate_int-sconsts DD_REG
    gen cmp_i %2, %1
	bxx[2] {slabel, 1f}
	bclr {const,0}, %3
	1:		yields	%3

proc cmxtxxior
with exact extend1 extend1 DD_REG
    gen cmp_b %2, %1
	bxx[2] {llabel,1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with exact extend2 extend2 DD_REG
    gen cmp_w %2, %1
	bxx[2] {llabel,1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with exact sconsts any_int DD_REG
    uses DD_REG=%1
    gen cmp_i %2, %a
	bxx[2] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with exact any_int sconsts DD_REG
    uses DD_REG=%2
    gen cmp_i %1, %a
	bxx[1] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with any_int-sconsts genreg DD_REG
    gen cmp_i %1, %2
	bxx[1] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with genreg any_int-sconsts DD_REG
    gen cmp_i %2, %1
	bxx[2] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with exact immediate_int-sconsts imm_cmp_int DD_REG
    gen cmp_i %1, %2
	bxx[1] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3
with exact imm_cmp_int immediate_int-sconsts DD_REG
    gen cmp_i %2, %1
	bxx[2] {slabel, 1f}
	bset {zero_const, 0},  %3
	1:		yields	%3

proc cmxtxx
with exact sconsts any_int
    uses DD_REG=%1
    gen cmp_i %2, %a
	sxx[2] %a
	neg_b %a
			yields {extend1, %a}
with exact any_int sconsts
    uses DD_REG=%2
    gen cmp_i %1, %a
	sxx[1] %a
	neg_b %a
			yields	{extend1, %a}
with any_int-sconsts genreg
    uses reusing %1,reusing %2,DD_REG
    gen cmp_i %1, %2
	sxx[1] %a
	neg_b %a
			yields	{extend1, %a}
with genreg any_int-sconsts
    uses reusing %1,reusing %2,DD_REG
    gen cmp_i %2, %1
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}
with exact extend1 extend1
    uses reusing %1,reusing %2,DD_REG
    gen cmp_b %2, %1
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}
with exact extend2 extend2
    uses reusing %1,reusing %2,DD_REG
    gen cmp_w %2, %1
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}
with exact immediate_int-sconsts imm_cmp_int
    uses reusing %2,DD_REG
    gen cmp_i %1, %2
	sxx[1] %a
	neg_b %a
			yields	{extend1, %a}
with exact imm_cmp_int immediate_int-sconsts 
    uses reusing %1,DD_REG
    gen cmp_i %2, %1
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}
with exact immediate_int-sconsts STACK
    uses DD_REG
    gen cmp_i %1, {post_inc_int, sp}
	sxx[1] %a
	neg_b %a
			yields	{extend1, %a}
with exact any_int STACK
    uses reusing %1,DD_REG=%1
    gen cmp_i {post_inc_int, sp}, %a
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}
with exact STACK
    uses DD_REG
    gen	move_i {post_inc_int, sp},%a
	cmp_i {post_inc_int, sp},%a
	sxx[2] %a
	neg_b %a
			yields	{extend1, %a}

pat cmi tlt and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("blt","bgt")
pat cmi tle and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("ble","bge")
pat cmi teq and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("beq","beq")
pat cmi tne and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bne","bne")
pat cmi tge and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bge","ble")
pat cmi tgt and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bgt","blt")

pat cmu tlt and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bcs","bhi")
pat cmu tle and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bls","bcc")
pat cmu teq and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("beq","beq")
pat cmu tne and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bne","bne")
pat cmu tge and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bcc","bls")
pat cmu tgt and $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxand("bhi","bcs")

pat cmi tlt ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bge","ble")
pat cmi tle ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bgt","blt")
pat cmi teq ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bne","bne")
pat cmi tne ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("beq","beq")
pat cmi tge ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("blt","bgt")
pat cmi tgt ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("ble","bge")

pat cmu tlt ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bcc","bls")
pat cmu tle ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bhi","bcs")
pat cmu teq ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bne","bne")
pat cmu tne ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("beq","beq")
pat cmu tge ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bcs","bhi")
pat cmu tgt ior $1==WORD_SIZE && $3==WORD_SIZE	call cmxtxxior("bls","bcc")

pat cmi tlt $1==WORD_SIZE			call cmxtxx("slt","sgt")
pat cmi tle $1==WORD_SIZE			call cmxtxx("sle","sge")
pat cmi teq $1==WORD_SIZE			call cmxtxx("seq","seq")
pat cmi tne $1==WORD_SIZE			call cmxtxx("sne","sne")
pat cmi tge $1==WORD_SIZE			call cmxtxx("sge","sle")
pat cmi tgt $1==WORD_SIZE			call cmxtxx("sgt","slt")

pat cmu tlt $1==WORD_SIZE			call cmxtxx("scs","shi")
pat cmu tle $1==WORD_SIZE			call cmxtxx("sls","scc")
pat cmu teq $1==WORD_SIZE			call cmxtxx("seq","seq")
pat cmu tne $1==WORD_SIZE			call cmxtxx("sne","sne")
pat cmu tge $1==WORD_SIZE			call cmxtxx("scc","sls")
pat cmu tgt $1==WORD_SIZE			call cmxtxx("shi","scs")


proc cmuzxx example cmu zlt
with exact sconsts any_int
    kills ALL
    uses DD_REG=%1
    gen cmp_i %2, %a
	bxx[2] {llabel, $2}
with exact any_int sconsts
    kills ALL
    uses DD_REG=%2
    gen cmp_i %1, %a
	bxx[1] {llabel, $2}
with any_int-sconsts genreg STACK
    gen cmp_i %1, %2
	bxx[1] {llabel, $2}
with genreg any_int-sconsts STACK
    gen cmp_i %2, %1
	bxx[2] {llabel, $2}
with exact immediate_int-sconsts imm_cmp_int
    kills ALL
    gen cmp_i %1, %2
	bxx[1] {llabel, $2}
with exact imm_cmp_int immediate_int-sconsts
    kills ALL
    gen cmp_i %2, %1
	bxx[2] {llabel, $2}
with exact immediate_int-sconsts STACK
    gen cmp_i %1, {post_inc_int, sp}
	bxx[1] {llabel, $2}
with exact any_int STACK
    uses reusing %1, DD_REG=%1
    gen cmp_i {post_inc_int, sp}, %a
	bxx[2] {llabel, $2}
with exact STACK
    uses DD_REG
    gen	move_i {post_inc_int, sp},%a
	cmp_i {post_inc_int, sp},%a
	bxx[2] {llabel, $2}
with data2-sconsts dreg2 STACK
    gen cmp_w %1, %2
        bxx[1] {llabel, $2}
with dreg2 data2-conreg2-sconsts STACK
    gen cmp_w %2, %1
        bxx[2] {llabel, $2}
with data1 dreg1 STACK
    gen cmp_b %1, %2
        bxx[1] {llabel, $2}
with dreg1 data1-conreg1 STACK
    gen cmp_b %2, %1
        bxx[2] {llabel, $2}

pat cmu zlt $1==WORD_SIZE		call cmuzxx("bcs","bhi")
pat cmu zle $1==WORD_SIZE		call cmuzxx("bls","bcc")
pat cmu zeq $1==WORD_SIZE		call cmuzxx("beq","beq")
pat cmu zne $1==WORD_SIZE		call cmuzxx("bne","bne")
pat cmu zge $1==WORD_SIZE		call cmuzxx("bcc","bls")
pat cmu zgt $1==WORD_SIZE		call cmuzxx("bhi","bcs")


#if TBL68881
proc cmf4zxx example cmf zlt
with FS_REG FS_REG
    gen	fcmp %1,%2
	bxx* {llabel, $2}

pat cmf zlt $1==4			call cmf4zxx("fblt")
pat cmf zle $1==4			call cmf4zxx("fble")
pat cmf zne $1==4			call cmf4zxx("fbne")
pat cmf zeq $1==4			call cmf4zxx("fbeq")
pat cmf zge $1==4			call cmf4zxx("fbge")
pat cmf zgt $1==4			call cmf4zxx("fbgt")

proc cmf8zxx example cmf zlt
with FD_REG FD_REG
    gen	fcmp %1,%2
	bxx* {llabel, $2}

pat cmf zlt $1==8			call cmf8zxx("fblt")
pat cmf zle $1==8			call cmf8zxx("fble")
pat cmf zne $1==8			call cmf8zxx("fbne")
pat cmf zeq $1==8			call cmf8zxx("fbeq")
pat cmf zge $1==8			call cmf8zxx("fbge")
pat cmf zgt $1==8			call cmf8zxx("fbgt")
#endif


proc loc1locciibxx example loc loc cii bne
with any1 extend1 STACK
    gen cmp_b %1,%2
	bxx[1] {llabel, $4}
with any1 any_int STACK
    uses reusing %1, DD_REG = %1
#if TBL68020 && WORD_SIZE==4
    gen extb_l %a
#else
    gen ext_w %a
#if WORD_SIZE==4
	ext_l %a
#endif
#endif
	cmp_i %2,%a
	bxx[2] {llabel, $4}

pat loc loc cii blt	$1==1 && $2==EM_WSIZE	call loc1locciibxx("blt","bgt")
pat loc loc cii ble	$1==1 && $2==EM_WSIZE	call loc1locciibxx("ble","bge")
pat loc loc cii bne	$1==1 && $2==EM_WSIZE	call loc1locciibxx("bne","bne")
pat loc loc cii beq	$1==1 && $2==EM_WSIZE	call loc1locciibxx("beq","beq")
pat loc loc cii bge	$1==1 && $2==EM_WSIZE	call loc1locciibxx("bge","ble")
pat loc loc cii bgt	$1==1 && $2==EM_WSIZE	call loc1locciibxx("bgt","blt")

#if WORD_SIZE==4
proc loc2locciibxx example loc loc cii bne
with any2 extend2 STACK
    gen cmp_w %1,%2
	bxx[1] {llabel, $4}
with any2 any4 STACK
    uses reusing %1, DD_REG = %1
    gen ext_l %a
	cmp_l %2,%a
	bxx[2] {llabel, $4}

pat loc loc cii blt	$1==2 && $2==EM_WSIZE	call loc2locciibxx("blt","bgt")
pat loc loc cii blt	$1==2 && $2==EM_WSIZE	call loc2locciibxx("blt","bgt")
pat loc loc cii ble	$1==2 && $2==EM_WSIZE	call loc2locciibxx("ble","bge")
pat loc loc cii bne	$1==2 && $2==EM_WSIZE	call loc2locciibxx("bne","bne")
pat loc loc cii beq	$1==2 && $2==EM_WSIZE	call loc2locciibxx("beq","beq")
pat loc loc cii bge	$1==2 && $2==EM_WSIZE	call loc2locciibxx("bge","ble")
pat loc loc cii bgt	$1==2 && $2==EM_WSIZE	call loc2locciibxx("bgt","blt")
#endif

proc bxx1_in example loc loc cii loc bne
with imm_cmp1 STACK
    gen cmp_b {const, low8($4)}, %1
	bxx* {llabel, $5}

#if WORD_SIZE!=2
proc bxx2_in example loc loc cii loc bne
with imm_cmp2 STACK
    gen cmp_w {const, loww($4)}, %1
	bxx* {llabel, $5}
#endif

proc bxx1_small example loc bne
with imm_cmp1-D_REG STACK
    gen cmp_b {const, $1}, %1
	bxx[1] {llabel, $2}
with imm_cmp2-D_REG STACK
    gen	cmp_w {const, $1}, %1
	bxx[1] {llabel, $2}
with data_int STACK
uses DD_REG = {small_const, $1}	/* uses moveq */
    gen cmp_i %1,%a
	bxx[2] {llabel, $2}

#if WORD_SIZE!=2
proc bxx2_small example loc bne
with imm_cmp2-D_REG STACK
    gen cmp_w {const, $1}, %1
	bxx[1] {llabel, $2}
with imm_cmp4 STACK
    gen cmp_l {const, $1}, %1
	bxx[2] {llabel, $2}
#endif

proc zxx1_in example loc loc cii zne
with test_set1 STACK
    gen test %1
	bxx* {llabel, $4}
with D_REG STACK
    gen test {dreg1, %1}
	bxx* {llabel, $4}

#if WORD_SIZE!=2
proc zxx2_in example loc loc cii zne
with test_set2 STACK
    gen test %1
	bxx* {llabel, $4}
with D_REG STACK
    gen test {dreg2, %1}
	bxx* {llabel, $4}
#endif

pat loc loc cii zlt $1==1 && $2==WORD_SIZE	call zxx1_in("blt")
pat loc loc cii zle $1==1 && $2==WORD_SIZE	call zxx1_in("ble")
pat loc loc cii zne $1==1 && $2==WORD_SIZE	call zxx1_in("bne")
pat loc loc cii zeq $1==1 && $2==WORD_SIZE	call zxx1_in("beq")
pat loc loc cii zge $1==1 && $2==WORD_SIZE	call zxx1_in("bge")
pat loc loc cii zgt $1==1 && $2==WORD_SIZE	call zxx1_in("bgt")

#if WORD_SIZE!=2
pat loc loc cii zlt $1==2 && $2==4	call zxx2_in("blt")
pat loc loc cii zle $1==2 && $2==4	call zxx2_in("ble")
pat loc loc cii zne $1==2 && $2==4	call zxx2_in("bne")
pat loc loc cii zeq $1==2 && $2==4	call zxx2_in("beq")
pat loc loc cii zge $1==2 && $2==4	call zxx2_in("bge")
pat loc loc cii zgt $1==2 && $2==4	call zxx2_in("bgt")
#endif

pat loc loc cii loc blt $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("blt")
pat loc loc cii loc ble $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("ble")
pat loc loc cii loc beq $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("beq")
pat loc loc cii loc bne $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bne")
pat loc loc cii loc bge $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bge")
pat loc loc cii loc bgt $1==1 && $2==WORD_SIZE && in_1($4) call bxx1_in("bgt")

#if WORD_SIZE!=2
pat loc loc cii loc blt $1==2 && $2==4 && in_2($4)	call bxx2_in("blt")
pat loc loc cii loc ble $1==2 && $2==4 && in_2($4)	call bxx2_in("ble")
pat loc loc cii loc beq $1==2 && $2==4 && in_2($4)	call bxx2_in("beq")
pat loc loc cii loc bne $1==2 && $2==4 && in_2($4)	call bxx2_in("bne")
pat loc loc cii loc bge $1==2 && $2==4 && in_2($4)	call bxx2_in("bge")
pat loc loc cii loc bgt $1==2 && $2==4 && in_2($4)	call bxx2_in("bgt")
#endif

/* the second instruction for bxx1_small is the other way around! */
pat loc blt $1>=0 && $1<128		call bxx1_small("bcs", "bgt")
pat loc ble $1>=0 && $1<128		call bxx1_small("bls", "bge")
pat loc beq $1>=0 && $1<128		call bxx1_small("beq", "beq")
pat loc bne $1>=0 && $1<128		call bxx1_small("bne", "bne")
pat loc bge $1>=0 && $1<128		call bxx1_small("bcc", "ble")
pat loc bgt $1>=0 && $1<128		call bxx1_small("bhi", "blt")

#if WORD_SIZE!=2
pat loc blt $1>=128 && $1<32768		call bxx2_small("bcs", "blt")
pat loc ble $1>=128 && $1<32768		call bxx2_small("bls", "ble")
pat loc beq $1>=128 && $1<32768		call bxx2_small("beq", "beq")
pat loc bne $1>=128 && $1<32768		call bxx2_small("bne", "bne")
pat loc bge $1>=128 && $1<32768		call bxx2_small("bcc", "bge")
pat loc bgt $1>=128 && $1<32768		call bxx2_small("bhi", "bgt")
#endif


pat loc loc cii lal sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
				leaving lal $4 sti $5
pat loc loc cii lol sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
				leaving lol $4 sti $5
pat loc loc cii lil sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
				leaving lil $4 sti $5
pat loc loc cii LLP lof sti $1 <= WORD_SIZE && $1>=$6 && $2==WORD_SIZE
				leaving LLP $4 lof $5 sti $6
pat loc loc cii lae sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
				leaving lae $4 sti $5
pat loc loc cii loe sti $1 <= WORD_SIZE && $1>=$5 && $2==WORD_SIZE
				leaving loe $4 sti $5

pat loc loc cii stl $1==1 && $2==WORD_SIZE && inreg($4)==reg_any
with memory1+DD_REG
    kills regvar($4, reg_any), use_index %xreg==regvar($4, reg_any)
    gen	move_b %1, {dreg1, regvar($4,reg_any)}
#if WORD_SIZE==2
	ext_w	{LOCAL,$4}
#else
#ifdef TBL68020
	extb_l	{LOCAL,$4}
#else /* TBL68020 */
	ext_w	{LOCAL,$4}
	ext_l	{LOCAL,$4}
#endif /* TBL68020 */
#endif

pat loc loc cii $1==2 && $2==4
#if WORD_SIZE==2
with D_REG
uses reusing %1, DD_REG4
    gen move %1,%a.1	yields	{extend2, %a}
with exact extend1
    uses reusing %1,DD_REG4
    gen move %1.reg,%a.1	yields	{extend1_4, %a}
with exact memory2
uses reusing %1,DD_REG4
    gen move %1, %a.1	yields	{extend2, %a}
#else
with DD_REG		yields	{extend2, %1}
with exact memory2
uses reusing %1,DD_REG=%1
			yields	{extend2, %a}
#endif

pat loc loc cii $1==1 && $2==WORD_SIZE
with DD_REG		yields	{extend1, %1}
with exact memory1
uses reusing %1,DD_REG = %1
    			yields	{extend1, %a}

#if WORD_SIZE==2
pat loc loc cii $1==1 && $2==4
with DD_REG
uses reusing %1, DD_REG4
    gen move %1, %a.1
			yields	{extend1_4, %a}
with exact memory1
uses reusing %1,DD_REG4
    gen move %1,%a.1	yields	{extend1_4, %a}
#endif

pat loc loc ciu $1==$2	/* skip this */
pat loc loc cui $1==$2	/* skip this */


/* The following rules should be handled by the peephole optimizer, I think */

#if WORD_SIZE==2
pat ldc dvu highw($1)==0 && loww($1)==2 && $2==4	leaving loc 1 sru 4
pat ldc dvu highw($1)==0 && loww($1)==4 && $2==4	leaving loc 2 sru 4
pat ldc dvu highw($1)==0 && loww($1)==8 && $2==4	leaving loc 3 sru 4
pat ldc dvu highw($1)==0 && loww($1)==16 && $2==4	leaving loc 4 sru 4
pat ldc dvu highw($1)==0 && loww($1)==32 && $2==4	leaving loc 5 sru 4
pat ldc dvu highw($1)==0 && loww($1)==64 && $2==4	leaving loc 6 sru 4
pat ldc dvu highw($1)==0 && loww($1)==128 && $2==4	leaving loc 7 sru 4
pat ldc dvu highw($1)==0 && loww($1)==256 && $2==4	leaving loc 8 sru 4
#endif

pat loc dvu $1==2 && $2==WORD_SIZE	leaving loc 1 sru WORD_SIZE
pat loc dvu $1==4 && $2==WORD_SIZE	leaving loc 2 sru WORD_SIZE
pat loc dvu $1==8 && $2==WORD_SIZE	leaving loc 3 sru WORD_SIZE
pat loc dvu $1==16 && $2==WORD_SIZE	leaving loc 4 sru WORD_SIZE
pat loc dvu $1==32 && $2==WORD_SIZE	leaving loc 5 sru WORD_SIZE
pat loc dvu $1==64 && $2==WORD_SIZE	leaving loc 6 sru WORD_SIZE
pat loc dvu $1==128 && $2==WORD_SIZE	leaving loc 7 sru WORD_SIZE
pat loc dvu $1==256 && $2==WORD_SIZE	leaving loc 8 sru WORD_SIZE

#if WORD_SIZE==2
pat ldc dvi highw($1)==0 && loww($1)==2 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 1 sri 4

pat ldc dvi highw($1)==0 && loww($1)==4 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 2 sri 4

pat ldc dvi highw($1)==0 && loww($1)==8 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 3 sri 4

pat ldc dvi highw($1)==0 && loww($1)==16 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 4 sri 4

pat ldc dvi highw($1)==0 && loww($1)==32 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 5 sri 4

pat ldc dvi highw($1)==0 && loww($1)==64 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 6 sri 4

pat ldc dvi highw($1)==0 && loww($1)==128 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 7 sri 4

pat ldc dvi highw($1)==0 && loww($1)==256 && $2==4
    with DD_REG4
    gen	test %1
	bpl {slabel,1f}
	add_l {const4,loww($1)-1},%1
	1: 			yields %1		leaving loc 8 sri 4
#endif /* WORD_SIZE==2 */

pat loc dvi $1==2 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 1 sri WORD_SIZE

pat loc dvi $1==4 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 2 sri WORD_SIZE

pat loc dvi $1==8 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 3 sri WORD_SIZE

pat loc dvi $1==16 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 4 sri WORD_SIZE

pat loc dvi $1==32 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 5 sri WORD_SIZE

pat loc dvi $1==64 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 6 sri WORD_SIZE

pat loc dvi $1==128 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 7 sri WORD_SIZE

pat loc dvi $1==256 && $2==WORD_SIZE
    with DD_REG
    gen	test %1
	bpl {slabel,1f}
	add_i {const,$1-1},%1
	1: 			yields %1	leaving loc 8 sri WORD_SIZE

/* The rest is all 2-bytes stuff */
#if WORD_SIZE==2
pat loc loc cii $1==4 && $2==2
with D_REG4
				yields %1.1
with any2-pre_post any2-pre_post
				yields %2

proc cmqtxx
with exact sconsts4 any4
    uses DD_REG4=%1
    gen cmp_l %2, %a
	s4xx[2] %a
	neg_b %a.1
			yields {extend1, %a.1}
with exact any4 sconsts4
    uses DD_REG4=%2
    gen cmp_l %1, %a
	s4xx[1] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with any4-sconsts4 genreg4
    uses reusing %1,reusing %2,DD_REG4
    gen cmp_l %1, %2
	s4xx[1] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with genreg4 any4-sconsts4
    uses reusing %1,reusing %2,DD_REG4
    gen cmp_l %2, %1
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact extend1_4 extend1_4
    uses reusing %1,reusing %2,DD_REG4
    gen cmp_b %2, %1
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact extend2 extend2
    uses reusing %1,reusing %2,DD_REG4
    gen cmp_w %2, %1
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact immediate4-sconsts4 imm_cmp4
    uses reusing %2,DD_REG4
    gen cmp_l %1, %2
	s4xx[1] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact imm_cmp4 immediate4-sconsts4 
    uses reusing %1,DD_REG4
    gen cmp_l %2, %1
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact immediate4-sconsts4 STACK
    uses DD_REG4
    gen cmp_l %1, {post_inc4, sp}
	s4xx[1] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact any4 STACK
    uses reusing %1,DD_REG4=%1
    gen cmp_l {post_inc4, sp}, %a
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}
with exact STACK
    uses DD_REG4
    gen	move_l {post_inc4, sp},%a
	cmp_l {post_inc4, sp},%a
	s4xx[2] %a
	neg_b %a.1
			yields	{extend1, %a.1}

pat cmi tlt $1==4			call cmqtxx("slt","sgt")
pat cmi tle $1==4			call cmqtxx("sle","sge")
pat cmi teq $1==4			call cmqtxx("seq","seq")
pat cmi tne $1==4			call cmqtxx("sne","sne")
pat cmi tge $1==4			call cmqtxx("sge","sle")
pat cmi tgt $1==4			call cmqtxx("sgt","slt")

pat cmu tlt $1==4			call cmqtxx("scs","shi")
pat cmu tle $1==4			call cmqtxx("sls","scc")
pat cmu teq $1==4			call cmqtxx("seq","seq")
pat cmu tne $1==4			call cmqtxx("sne","sne")
pat cmu tge $1==4			call cmqtxx("scc","sls")
pat cmu tgt $1==4			call cmqtxx("shi","scs")


proc cmqzxx example cmu zlt
with zero_const4 test_set4 STACK
    /* kills ALL */
    gen test %2
	bxx[1] {llabel, $2}
with exact sconsts4-zero_const4 any4
    kills ALL
    uses DD_REG4=%1
    gen cmp_l %2, %a
	bxx[2] {llabel, $2}
with exact any4 sconsts4
    kills ALL
    uses DD_REG4=%2
    gen cmp_l %1, %a
	bxx[1] {llabel, $2}
with any4-sconsts4-zero_const4 genreg4 STACK
    gen cmp_l %1, %2
	bxx[1] {llabel, $2}
with genreg4 any4-sconsts4-zero_const4 STACK
    gen cmp_l %2, %1
	bxx[2] {llabel, $2}
with exact immediate4-sconsts4-zero_const4 imm_cmp4
    kills ALL
    gen cmp_l %1, %2
	bxx[1] {llabel, $2}
with exact imm_cmp4 immediate4-sconsts4-zero_const4
    kills ALL
    gen cmp_l %2, %1
	bxx[2] {llabel, $2}
with exact immediate4-sconsts4-zero_const4 STACK
    gen cmp_l %1, {post_inc4, sp}
	bxx[1] {llabel, $2}
with exact any4 STACK
    uses reusing %1, DD_REG4=%1
    gen cmp_l {post_inc4, sp}, %a
	bxx[2] {llabel, $2}
with exact STACK
    uses DD_REG4
    gen	move_l {post_inc4, sp},%a
	cmp_l {post_inc4, sp},%a
	bxx[2] {llabel, $2}
with data2-sconsts dreg2 STACK
    gen cmp_w %1, %2
        bxx[1] {llabel, $2}
with dreg2 data2-conreg2-sconsts STACK
    gen cmp_w %2, %1
        bxx[2] {llabel, $2}
with data1 dreg1 STACK
    gen cmp_b %1, %2
        bxx[1] {llabel, $2}
with dreg1 data1-conreg1 STACK
    gen cmp_b %2, %1
        bxx[2] {llabel, $2}

pat cmi zlt $1==4		call cmqzxx("blt","bgt")
pat cmi zle $1==4		call cmqzxx("ble","bge")
pat cmi zeq $1==4		call cmqzxx("beq","beq")
pat cmi zne $1==4		call cmqzxx("bne","bne")
pat cmi zge $1==4		call cmqzxx("bge","ble")
pat cmi zgt $1==4		call cmqzxx("bgt","blt")

pat cms zeq $1==4		call cmqzxx("beq","beq")
pat cms zne $1==4		call cmqzxx("bne","bne")

pat cmu zlt $1==4		call cmqzxx("bcs","bhi")
pat cmu zle $1==4		call cmqzxx("bls","bcc")
pat cmu zeq $1==4		call cmqzxx("beq","beq")
pat cmu zne $1==4		call cmqzxx("bne","bne")
pat cmu zge $1==4		call cmqzxx("bcc","bls")
pat cmu zgt $1==4		call cmqzxx("bhi","bcs")

pat ldc cms zeq loww($1)==0 && highw($1)==0 && $2==4
with test_set4 STACK
    gen test %1
	beq {llabel, $3}

pat ldc cms zne loww($1)==0 && highw($1)==0 && $2==4
with test_set4 STACK
    gen test %1
	bne {llabel, $3}
#endif
