2328 lines
		
	
	
	
		
			62 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			2328 lines
		
	
	
	
		
			62 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
"$Header$"
 | 
						|
/*
 | 
						|
 * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
						|
 *
 | 
						|
 *          This product is part of the Amsterdam Compiler Kit.
 | 
						|
 *
 | 
						|
 * Permission to use, sell, duplicate or disclose this software must be
 | 
						|
 * obtained in writing. Requests for such permissions may be sent to
 | 
						|
 *
 | 
						|
 *      Dr. Andrew S. Tanenbaum
 | 
						|
 *      Wiskundig Seminarium
 | 
						|
 *      Vrije Universiteit
 | 
						|
 *      Postbox 7161
 | 
						|
 *      1007 MC Amsterdam
 | 
						|
 *      The Netherlands
 | 
						|
 *
 | 
						|
 */
 | 
						|
 | 
						|
#define SL 4
 | 
						|
#define SSL "4"
 | 
						|
 | 
						|
/********************************************************
 | 
						|
 * Back end tables for Intel 8086			*
 | 
						|
 * Author : Ed Keizer					*
 | 
						|
 *							*
 | 
						|
 * wordsize = 2 bytes, pointersize = 2 bytes.		*
 | 
						|
 *							*
 | 
						|
 * Register bp is used as LB, sp is used for SP.	*
 | 
						|
 * Some global variables are used:			*
 | 
						|
 * - .reghp	: the heap pointer			*
 | 
						|
 * - .ignmask	: trap ignore mask			*
 | 
						|
 * - .trppc	: address of user defined trap handler	*
 | 
						|
 *							*
 | 
						|
 * Floating point arithmetic and constants are not	*
 | 
						|
 * implemented.
 | 
						|
 *							*
 | 
						|
 ********************************************************/
 | 
						|
 | 
						|
/* #define DEEPER	1
 | 
						|
/*	When DEEPER is disabled, the table contains some
 | 
						|
	heuristics based on the assumption that look-ahead will
 | 
						|
	be minimal.
 | 
						|
	Example: Addition of constants to registers will no take
 | 
						|
	place via ax, but in an address register, in the rules for ads.
 | 
						|
	Thereby assuming that the resulting register will be used
 | 
						|
	to access memory.
 | 
						|
	When DEEPER is enabled these heuristics are disabled
 | 
						|
	thereby allowing the code-generator too see for itself
 | 
						|
	which code will be shorter.
 | 
						|
*/
 | 
						|
 | 
						|
#define SPEED		1
 | 
						|
/* This definition produces a slightly different table,
 | 
						|
   producing slightly less efficient code with greater speed
 | 
						|
*/
 | 
						|
 | 
						|
#ifdef SPEED
 | 
						|
 | 
						|
#define NO	nocoercions :
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
#define NO
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
EM_WSIZE=2
 | 
						|
EM_PSIZE=2
 | 
						|
EM_BSIZE=SL
 | 
						|
 | 
						|
SIZEFACTOR=5
 | 
						|
 | 
						|
REGISTERS:
 | 
						|
 | 
						|
al	= ("al", 2), REG1, ACC1.
 | 
						|
ah	= ("ah", 2), REG1.
 | 
						|
bl	= ("bl", 2), REG1.
 | 
						|
bh	= ("bh", 2), REG1.
 | 
						|
cl	= ("cl", 2), REG1, SHIFT_CREG.
 | 
						|
ch	= ("ch", 2), REG1.
 | 
						|
dl	= ("dl", 2), REG1.
 | 
						|
dh	= ("dh", 2), REG1.
 | 
						|
ax	= ("ax", 2, al, ah), REG, GENREG, ACC.
 | 
						|
bx	= ("bx", 2, bl, bh), REG, GENREG, BREG, BXREG, ADDREG.
 | 
						|
cx	= ("cx", 2, cl, ch), REG, GENREG, CXREG, SHIFT_CREG.
 | 
						|
dx	= ("dx", 2, dl, dh), REG, GENREG, DXREG.
 | 
						|
si	= ("si", 2), REG, IREG, SIREG, ADDREG.
 | 
						|
di	= ("di", 2), REG, IREG, DIREG, ADDREG.
 | 
						|
bp	= ("bp", 2), BREG.
 | 
						|
 | 
						|
TOKENS:
 | 
						|
 | 
						|
/********************************
 | 
						|
 * Types on the EM-machine	*
 | 
						|
 ********************************/
 | 
						|
 | 
						|
ANYCON		= { INT val ; } 		2 cost=(2, 1) "%[val]"
 | 
						|
ADDR_EXTERN	= { STRING off ; }		2 cost=(2, 1) "%[off]"
 | 
						|
EXTERN1 	= { STRING off ; }		2 cost=(2,12) "(%[off])"
 | 
						|
EXTERN2 	= { STRING off ; }		2 cost=(2,12) "(%[off])"
 | 
						|
ADDR_LOCAL	= { INT ind ; } 		2 cost=(1, 9) "%[ind](bp)"
 | 
						|
LOCAL2		= { INT ind, size ; }		2 cost=(1,15) "%[ind](bp)"
 | 
						|
LOCAL1		= { INT ind, size ; }		2 cost=(1,15) "%[ind](bp)"
 | 
						|
 | 
						|
 | 
						|
/********************************************************
 | 
						|
 * Now mostly addressing modes of target machine	*
 | 
						|
 ********************************************************/
 | 
						|
 | 
						|
 | 
						|
/*****************************************
 | 
						|
 * 'Half modes' consisting of summations *
 | 
						|
 * of constant and or register(s)	 *
 | 
						|
 *****************************************/
 | 
						|
 | 
						|
reg_off    = { REGISTER reg; STRING off; } 2 cost=(1, 9) "%[off](%[reg])"
 | 
						|
bpreg_off  = { REGISTER reg; INT ind; }    2 cost=(1,11) "%[ind](bp)(%[reg])"
 | 
						|
 | 
						|
/**************************************************
 | 
						|
 * Indirect through registers and the modes above *
 | 
						|
 * Token names ending on digits are indirect	  *
 | 
						|
 **************************************************/
 | 
						|
 | 
						|
 | 
						|
ind_reg2	= { REGISTER reg; }		2 cost=(0,11) "(%[reg])"
 | 
						|
ind_regoff2	= { REGISTER reg; STRING off; } 2 cost=(1,15) "%[off](%[reg])"
 | 
						|
ind_bpregoff2	= { REGISTER reg; INT ind; }	2 cost=(1,18)
 | 
						|
							  "%[ind](bp)(%[reg])"
 | 
						|
 | 
						|
ind_reg1	= { REGISTER reg; }		2 cost=(0,11) "(%[reg])"
 | 
						|
ind_regoff1	= { REGISTER reg; STRING off; } 2 cost=(1,15) "%[off](%[reg])"
 | 
						|
ind_bpregoff1	= { REGISTER reg; INT ind; }	2 cost=(1,18)
 | 
						|
							  "%[ind](bp)(%[reg])"
 | 
						|
 | 
						|
TOKENEXPRESSIONS:
 | 
						|
 | 
						|
/* SCRATCH REGISTERS */
 | 
						|
X_ACC		= ACC*SCRATCH
 | 
						|
X_ACC1		= ACC1*SCRATCH
 | 
						|
X_REG		= REG*SCRATCH
 | 
						|
X_BXREG 	= BXREG*SCRATCH
 | 
						|
X_DXREG 	= DXREG*SCRATCH
 | 
						|
X_CXREG 	= CXREG*SCRATCH
 | 
						|
X_SIREG 	= SIREG*SCRATCH
 | 
						|
X_DIREG 	= DIREG*SCRATCH
 | 
						|
X_ADDREG	= ADDREG*SCRATCH
 | 
						|
 | 
						|
/* Mode refering to a word in memory */
 | 
						|
memory2 	= EXTERN2 + ind_reg2 + ind_regoff2 + ind_bpregoff2 + LOCAL2
 | 
						|
 | 
						|
/* Mode refering to a byte in memory */
 | 
						|
memory1 	= EXTERN1 + ind_reg1 + ind_regoff1 + ind_bpregoff1 + LOCAL1
 | 
						|
 | 
						|
/* Modes allowed in instructions */
 | 
						|
const		= ANYCON + ADDR_EXTERN
 | 
						|
anyreg		= REG + BREG
 | 
						|
rm		= anyreg + memory2
 | 
						|
rmorconst	= const + rm
 | 
						|
regorconst	= const + anyreg
 | 
						|
dest		= REG + memory2
 | 
						|
 | 
						|
rm1		= REG1 + memory1
 | 
						|
rmorconst1	= const + rm1
 | 
						|
regorconst12	= REG1 + GENREG + const
 | 
						|
dest1		= REG1 + memory1
 | 
						|
 | 
						|
/* Modes used to indicate tokens to be removed from the fakestack */
 | 
						|
reg_indexed	= ind_reg2 + ind_regoff2 + ind_reg1 + ind_regoff1
 | 
						|
lb_indexed	= ind_bpregoff2 + ind_bpregoff1
 | 
						|
indexed 	= reg_indexed + lb_indexed
 | 
						|
externals	= EXTERN2 + EXTERN1
 | 
						|
locals		= LOCAL2 + LOCAL1
 | 
						|
all_locals	= locals + lb_indexed
 | 
						|
indirects	= externals + reg_indexed
 | 
						|
referals	= indirects + locals
 | 
						|
 | 
						|
/* Miscellaneous */
 | 
						|
halfindir	= reg_off + bpreg_off + ADDR_LOCAL
 | 
						|
some_off	= halfindir + ADDR_EXTERN + ADDREG
 | 
						|
a_word		= rmorconst + rm1 + halfindir
 | 
						|
no_reg_off	= rmorconst + rm1 + ADDR_LOCAL
 | 
						|
 | 
						|
CODE:
 | 
						|
 | 
						|
/********************************************************
 | 
						|
 * Group 1 : load instructions. 			*
 | 
						|
 *							*
 | 
						|
 * For most load instructions no code is generated.	*
 | 
						|
 * Action : put something on the fake-stack.		*
 | 
						|
 ********************************************************/
 | 
						|
 | 
						|
loc 		| |		| {ANYCON, $1}				| |
 | 
						|
ldc		| |		| {ANYCON, highw(1)} {ANYCON, loww(1)}	| |
 | 
						|
lol		| |		| {LOCAL2, $1, 2}			| |
 | 
						|
loe		| |		| {EXTERN2, $1} 			| |
 | 
						|
lil		| |	allocate(ADDREG={ind_regoff2, bp, tostring($1)})
 | 
						|
				| {ind_reg2, %[a]}			| |
 | 
						|
lof		| nocoercions : reg_off |
 | 
						|
				| {ind_regoff2, %[1.reg],
 | 
						|
					%[1.off]+"+"+tostring($1)}	| |
 | 
						|
...		| ADDREG |	| {ind_regoff2,%[1],tostring($1)} | |
 | 
						|
...		| nocoercions : bpreg_off  |
 | 
						|
			  | {ind_bpregoff2,%[1.reg], %[1.ind]+$1} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN|
 | 
						|
			    | {EXTERN2,%[1.off]+"+"+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_LOCAL |
 | 
						|
				      | {LOCAL2, %[1.ind] + $1,2} | |
 | 
						|
lal		| |		| {ADDR_LOCAL, $1}			| |
 | 
						|
lae		| |		| {ADDR_EXTERN, $1}			| |
 | 
						|
lpb		| |		|			| adp SL  |
 | 
						|
lxl $1==0	| |		| {ADDR_LOCAL, 0}			| |
 | 
						|
lxl $1==1	| |		| {LOCAL2 ,SL, 2}			| |
 | 
						|
lxl $1==2	| |	allocate(ADDREG={ind_regoff2, bp, SSL})
 | 
						|
				| {ind_regoff2,%[a], SSL}		| |
 | 
						|
lxl $1>2	| |	allocate(ADDREG={ind_regoff2, bp, SSL},
 | 
						|
				 CXREG={ANYCON,$1-1})
 | 
						|
			"1:\tmov %[a],4(%[a])"
 | 
						|
			"loop 1b"
 | 
						|
			samecc erase(%[a]) erase(%[b])
 | 
						|
				| %[a]					| |
 | 
						|
lxa $1==0	| |		| {ADDR_LOCAL, SL}			| |
 | 
						|
lxa $1==1	| |	allocate(ADDREG={ind_regoff2, bp, SSL })
 | 
						|
				| {reg_off, %[a], SSL } 		| |
 | 
						|
lxa $1==2	| |	allocate(ADDREG={ind_regoff2, bp, SSL })
 | 
						|
			move({ind_regoff2, %[a], SSL }, %[a])
 | 
						|
				| {reg_off, %[a], SSL } 		| |
 | 
						|
lxa $1 > 2	| |	allocate(ADDREG={ind_regoff2,bp,SSL},
 | 
						|
				 CXREG={ANYCON,$1-1})
 | 
						|
			"1:\tmov %[a],4(%[a])"
 | 
						|
			"loop 1b"
 | 
						|
			samecc erase(%[a]) erase(%[b])
 | 
						|
				| {reg_off, %[a], SSL } 		| |
 | 
						|
dch		| |		|			       | loi 2	  |
 | 
						|
loi $1==2	| ADDREG     |	| {ind_reg2, %[1]}			| |
 | 
						|
...		| nocoercions : reg_off    |
 | 
						|
			    | {ind_regoff2, %[1.reg], %[1.off]} | |
 | 
						|
...		| nocoercions : bpreg_off  |
 | 
						|
			| {ind_bpregoff2, %[1.reg], %[1.ind]}	| |
 | 
						|
...		| nocoercions : ADDR_EXTERN|
 | 
						|
			| {EXTERN2, %[1.off]}			| |
 | 
						|
...		| nocoercions : ADDR_LOCAL |
 | 
						|
			| {LOCAL2, %[1.ind],2}			| |
 | 
						|
loi $1==1	| ADDREG     |	| {ind_reg1, %[1]}			| |
 | 
						|
...		| nocoercions : reg_off    |
 | 
						|
				| {ind_regoff1, %[1.reg], %[1.off]}	| |
 | 
						|
...		| nocoercions : bpreg_off  |
 | 
						|
			| {ind_bpregoff1, %[1.reg], %[1.ind]}	| |
 | 
						|
...		| nocoercions : ADDR_EXTERN |
 | 
						|
			| {EXTERN1, %[1.off]}			| |
 | 
						|
...		| nocoercions : ADDR_LOCAL |
 | 
						|
			| {LOCAL1, %[1.ind],1}			| |
 | 
						|
loi $1==4	| ADDREG     |	| {ind_regoff2,%[1],"2"} {ind_reg2,%[1]}| |
 | 
						|
...		| nocoercions : reg_off    |
 | 
						|
				| {ind_regoff2,%[1.reg], %[1.off]+"+2"}
 | 
						|
				  {ind_regoff2,%[1.reg], %[1.off]}	| |
 | 
						|
...		| nocoercions : bpreg_off  |
 | 
						|
			| {ind_bpregoff2, %[1.reg], %[1.ind]+2}
 | 
						|
				  {ind_bpregoff2, %[1.reg], %[1.ind]}	| |
 | 
						|
...		| nocoercions : ADDR_LOCAL |	|
 | 
						|
			      {LOCAL2,%[1.ind]+2,2} {LOCAL2,%[1.ind],2} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN|	| {EXTERN2, %[1.off]+"+2"}
 | 
						|
				  {EXTERN2, %[1.off]}			| |
 | 
						|
loi $1>4	| X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			allocate(CXREG={ANYCON,$1})
 | 
						|
			"sub sp,cx"
 | 
						|
			"sar cx,1"
 | 
						|
			"mov di,sp"
 | 
						|
			"rep movs"
 | 
						|
			erase(%[a]) erase(%[1]) | | | (8,8+$1*9)
 | 
						|
...		| X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			allocate(CXREG={ANYCON,$1})
 | 
						|
			"call .loi"
 | 
						|
			erase(%[a]) erase(%[1]) | | | (3,32+$1*9)
 | 
						|
los $1==2	| X_CXREG X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .loi"
 | 
						|
			erase(%[1]) erase(%[2]) 		|	| |
 | 
						|
los !defined($1)| rm X_CXREG X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"call .loi"
 | 
						|
			erase(%[2]) erase(%[3]) 		|	| |
 | 
						|
ldl		| |		| {LOCAL2, $1+2,2} {LOCAL2, $1,2}	| |
 | 
						|
lde		| |		| {EXTERN2, $1+"+2"} {EXTERN2, $1}	| |
 | 
						|
ldf		| nocoercions : reg_off |
 | 
						|
				| {ind_regoff2, %[1.reg],
 | 
						|
					%[1.off]+"+2+"+tostring($1)}
 | 
						|
				  {ind_regoff2, %[1.reg],
 | 
						|
					%[1.off]+"+"+tostring($1)}	| |
 | 
						|
...		| ADDREG |
 | 
						|
				| {ind_regoff2, %[1], tostring($1+2)}
 | 
						|
				  {ind_regoff2, %[1], tostring($1)}	| |
 | 
						|
...		| nocoercions : bpreg_off |
 | 
						|
				| {ind_bpregoff2,%[1.reg], %[1.ind]+2+$1}
 | 
						|
				  {ind_bpregoff2,%[1.reg], %[1.ind]+$1} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN |
 | 
						|
				| {EXTERN2,%[1.off]+"+2+"+tostring($1)}
 | 
						|
				  {EXTERN2,%[1.off]+"+"+tostring($1)}	| |
 | 
						|
...		| nocoercions : ADDR_LOCAL |
 | 
						|
				| {LOCAL2, %[1.ind] + $1 + 2, 2}
 | 
						|
				  {LOCAL2, %[1.ind] + $1, 2}		| |
 | 
						|
lpi		| |		| {ADDR_EXTERN, $1}			| |
 | 
						|
/* This code sequence is generated by the C-compiler to tackle
 | 
						|
   char parameters, on the 8086 it reduces to nil */
 | 
						|
lol lal sti $1==$2 && $3<=2 | | |					| |
 | 
						|
 | 
						|
/****************************************************************
 | 
						|
 * Group 2 : Store instructions.				*
 | 
						|
 *								*
 | 
						|
 * These instructions are likely to ruin the fake-stack.	*
 | 
						|
 * We don't expect many items on the fake-stack anyway		*
 | 
						|
 * because we seem to have evaluated an expression just now.	*
 | 
						|
 ****************************************************************/
 | 
						|
 | 
						|
stl		| regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			move(%[1],{ind_regoff2,bp,tostring($1)})|	| |
 | 
						|
...		| nocoercions : STACK |
 | 
						|
			"pop $1(bp)" samecc			|  | |(2,26)
 | 
						|
ste		| regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			move(%[1], {EXTERN2, $1 })		|	| |
 | 
						|
...		| nocoercions : STACK | "pop ($1)" samecc	| | |
 | 
						|
sil		| regorconst |
 | 
						|
			allocate(ADDREG={ind_regoff2, bp, tostring($1)})
 | 
						|
			remove(referals)
 | 
						|
			move(%[1], {ind_reg2, %[a]})		|	| |
 | 
						|
stf		| ADDREG regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1],tostring($1)})|	| |
 | 
						|
...		| nocoercions : ADDREG STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop $1(%[1])" samecc			      | | |
 | 
						|
...		| reg_off regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1.reg],
 | 
						|
				%[1.off]+"+"+tostring($1)})	|	| |
 | 
						|
...		| nocoercions : halfindir STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop $1+%[1]" samecc			      | | |
 | 
						|
...		| ADDR_LOCAL | | 			| stl %[1.ind]+$1 |
 | 
						|
...		| bpreg_off regorconst |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			move(%[2],{ind_bpregoff2,%[1.reg],
 | 
						|
					%[1.ind]+$1})		|	| |
 | 
						|
/*
 | 
						|
...		| ADDR_EXTERN regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			move(%[2],{EXTERN2,%[1.off]+"+"+tostring($1)})| | |
 | 
						|
*/
 | 
						|
sti $1==2	| ADDREG regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_reg2,%[1]})		|	| |
 | 
						|
...		| nocoercions : ADDREG STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop (%[1])" samecc			      | | |
 | 
						|
...		| reg_off regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1.reg],%[1.off]})  |	| |
 | 
						|
...		| nocoercions : reg_off STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop %[1]" samecc			      | | |
 | 
						|
...		| ADDR_LOCAL | 				| | stl %[1.ind] |
 | 
						|
...		| bpreg_off regorconst |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			move(%[2],{ind_bpregoff2,%[1.reg], %[1.ind]}) | | |
 | 
						|
...		| nocoercions : bpreg_off STACK |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			"pop %[1]" samecc			      | | |
 | 
						|
...		| ADDR_EXTERN regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			move(%[2],{EXTERN2,%[1.off]})		|	| |
 | 
						|
...		| nocoercions : ADDR_EXTERN STACK |
 | 
						|
			remove(indirects)
 | 
						|
			"pop (%[1])" samecc			      | | |
 | 
						|
sti $1==1	| ADDREG regorconst12 |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_reg1,%[1]})		|	| |
 | 
						|
...		| reg_off regorconst12 |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff1,%[1.reg],%[1.off]})  |	| |
 | 
						|
...		| bpreg_off regorconst12 |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			move(%[2],{ind_bpregoff1,%[1.reg], %[1.ind]}) | | |
 | 
						|
...		| ADDR_EXTERN regorconst12 |
 | 
						|
			remove(indirects)
 | 
						|
			move(%[2],{EXTERN1,%[1.off]})		|	| |
 | 
						|
...		| ADDR_LOCAL regorconst12 |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals,
 | 
						|
				%[ind]<=%[1.ind] && %[ind]+%[size]>%[1.ind] )
 | 
						|
			move(%[2],{ind_regoff1, bp, tostring(%[1.ind])})
 | 
						|
								|	| |
 | 
						|
sti $1==4	| ADDREG regorconst regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_reg2,%[1]})
 | 
						|
			move(%[3],{ind_regoff2,%[1],"2"})	|	| |
 | 
						|
...		| reg_off regorconst regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1.reg],%[1.off]})
 | 
						|
			move(%[3],{ind_regoff2,%[1.reg],%[1.off]+"+2"})| | |
 | 
						|
...		| bpreg_off regorconst regorconst |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			move(%[2],{ind_bpregoff2,%[1.reg], %[1.ind]})
 | 
						|
			move(%[3],{ind_bpregoff2,%[1.reg], %[1.ind]+2})| | |
 | 
						|
...		| ADDR_EXTERN regorconst regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			move(%[2],{EXTERN2,%[1.off]})
 | 
						|
			move(%[3],{EXTERN2,%[1.off]+"+2"})	|	| |
 | 
						|
...		| ADDR_LOCAL regorconst regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=%[1.ind] && %[ind]<%[1.ind]+4 )
 | 
						|
			move(%[2],{ind_regoff2, bp, tostring(%[1.ind])})
 | 
						|
			move(%[3],{ind_regoff2, bp,
 | 
						|
						tostring(%[1.ind]+2)})| | |
 | 
						|
sti $1>4	| X_DIREG |
 | 
						|
			remove(ALL)
 | 
						|
			allocate(CXREG={ANYCON,$1/2})
 | 
						|
			"mov si,sp"
 | 
						|
			"rep movs"
 | 
						|
			"mov sp,si"
 | 
						|
			erase(%[1]) erase(%[a]) |	| | (5,4+$1*8)
 | 
						|
/* This sort of construction gives problems in the codegenerator
 | 
						|
   because of the potential verly large lookahead
 | 
						|
...		| X_ADDREG |
 | 
						|
			remove(ALL)
 | 
						|
			"pop (%[1])"
 | 
						|
			"add %[1],2"
 | 
						|
			erase(%[1])		| %[1]	| sti $1-2 | (5,30)
 | 
						|
*/
 | 
						|
sts $1==2	| X_CXREG X_DIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sti"
 | 
						|
			erase(%[1]) erase(%[2]) 		|	| |
 | 
						|
sdl		|	  |			  |	| stl $1 stl $1+2 |
 | 
						|
sde		|	  |			  |  | ste $1 ste $1+"+2" |
 | 
						|
sdf		| ADDREG regorconst regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1],tostring($1)})
 | 
						|
			move(%[3],{ind_regoff2,%[1],tostring($1+2)})|   | |
 | 
						|
...		| nocoercions : ADDREG STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop $1(%[1])"
 | 
						|
			"pop %($1+2%)(%[1])" samecc		      | | |
 | 
						|
...		| reg_off regorconst regorconst |
 | 
						|
			remove(referals)
 | 
						|
			move(%[2],{ind_regoff2,%[1.reg],
 | 
						|
				%[1.off]+"+"+tostring($1)})
 | 
						|
			move(%[3],{ind_regoff2,%[1.reg],
 | 
						|
				%[1.off]+"+"+tostring($1+2)})	|	| |
 | 
						|
...		| nocoercions : halfindir STACK |
 | 
						|
			remove(referals)
 | 
						|
			"pop $1+%[1]"
 | 
						|
			"pop %($1+2%)+%[1]" samecc		      | | |
 | 
						|
	/* Funny things happen when the sign changes in the stl parameters */
 | 
						|
...		| ADDR_LOCAL | |      | stl %[1.ind]+$1 stl %[1.ind]+$1+2 |
 | 
						|
...		| bpreg_off regorconst regorconst |
 | 
						|
			remove(all_locals)
 | 
						|
			remove(indexed)
 | 
						|
			move(%[2],{ind_bpregoff2,%[1.reg],
 | 
						|
					%[1.ind]+$1})
 | 
						|
			move(%[3],{ind_bpregoff2,%[1.reg],
 | 
						|
					%[1.ind]+$1+2})		|	| |
 | 
						|
...		| halfindir regorconst |
 | 
						|
			remove(referals)
 | 
						|
			"mov %[1],%[2]"
 | 
						|
			samecc | %[1] | stf $1+2 | (0,12)+%[1]+%[2]+%[1]
 | 
						|
 | 
						|
/****************************************************************
 | 
						|
 * Group 3 : Integer arithmetic.				*
 | 
						|
 *								*
 | 
						|
 * Implemented (sometimes with the use of subroutines) :	*
 | 
						|
 * all 2 and 4 byte arithmetic. 				*
 | 
						|
 ****************************************************************/
 | 
						|
 | 
						|
adi $1==2	| NO X_REG rmorconst |
 | 
						|
			"add %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| rmorconst X_REG |
 | 
						|
			"add %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"add %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"add %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
adi $1==4	| NO X_REG X_REG rmorconst rmorconst |
 | 
						|
			"add %[1],%[3]"
 | 
						|
			"adc %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(4,6)+%[4]+%[3]
 | 
						|
...		| X_ACC X_REG const rmorconst |
 | 
						|
			"add %[1],%[3]"
 | 
						|
			"adc %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(5,7)+%[4]
 | 
						|
...		| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"add %[3],%[1]"
 | 
						|
			"adc %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(4,6)+%[1]+%[2]
 | 
						|
...		| const rmorconst X_ACC X_REG |
 | 
						|
			"add %[3],%[1]"
 | 
						|
			"adc %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(5,7)+%[2]
 | 
						|
adi !defined($1)| X_CXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .adi"
 | 
						|
			erase(%[1]) erase(%[2])        | ax | |
 | 
						|
sbi $1==2	| rmorconst X_REG |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2])      | %[2] | | (2,3) + %[1]
 | 
						|
...		| const X_ACC |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2])      | %[2] | | (3,4)
 | 
						|
...		| NO X_REG rmorconst |
 | 
						|
			"sub %[1],%[2]"
 | 
						|
			"neg %[1]"
 | 
						|
			erase(%[1]) setcc(%[1])      | %[1] | | (4,6) + %[2]
 | 
						|
...		| NO X_ACC const |
 | 
						|
			"sub %[1],%[2]"
 | 
						|
			"neg %[1]"
 | 
						|
			erase(%[1]) setcc(%[1])      | %[1] | | (5,7)
 | 
						|
sbi $1==4	| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"sub %[3],%[1]"
 | 
						|
			"sbb %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(4,6)+%[1]+%[2]
 | 
						|
...		| const rmorconst-ACC X_ACC X_REG |
 | 
						|
			"sub %[3],%[1]"
 | 
						|
			"sbb %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(5,7)+%[2]
 | 
						|
sbi !defined($1)| X_CXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sbi"
 | 
						|
			erase(%[1]) erase(%[2])        | ax | |
 | 
						|
mli $1==2	| X_ACC rm |
 | 
						|
			allocate(%[2],DXREG)
 | 
						|
			"mul %[2]"
 | 
						|
			/* mul and imul have same low order result
 | 
						|
			   but mul is faster
 | 
						|
			*/
 | 
						|
			nocc erase(%[1])	    | %[1]  | |(2,118)+%[2]
 | 
						|
...		| rm-ACC X_ACC |
 | 
						|
			allocate(%[1],DXREG)
 | 
						|
			"mul %[1]"
 | 
						|
			nocc erase(%[2])	    | %[2]  | |(2,118)+%[1]
 | 
						|
mli $1==4	| SIREG DIREG BXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mli4"
 | 
						|
			erase(ax) setcc(dx)	    | dx ax | |
 | 
						|
/* Not now,
 | 
						|
mli !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mli"		    |	    | |
 | 
						|
*/
 | 
						|
dvi $1==2	| rm-ACC X_ACC |
 | 
						|
			allocate(DXREG)
 | 
						|
			"cwd"
 | 
						|
			"idiv %[1]"
 | 
						|
			erase(%[2])		       | ax | |(3,176)+%[1]
 | 
						|
dvi $1==4	| |	remove(ALL)
 | 
						|
			"call .dvi4"		    | cx ax | |
 | 
						|
/*
 | 
						|
dvi !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dvi" erase(%[1])     |	    | |
 | 
						|
*/
 | 
						|
#ifdef LONGEMPAT
 | 
						|
loc loc cii dvi loc loc cii $1==2 && $2==4 && $4==4 && $5==4 && $6==2
 | 
						|
		| rm-ACC-DXREG X_ACC X_DXREG |
 | 
						|
			"idiv %[1]"
 | 
						|
			erase(%[2]) erase(%[3])        | ax | |(2,171)+%[1]
 | 
						|
#endif
 | 
						|
rmi $1==2	| rm-ACC X_ACC |
 | 
						|
			allocate(DXREG)
 | 
						|
			"cwd"
 | 
						|
			"idiv %[1]"
 | 
						|
			erase(%[2])		       | dx | |(3,176)+%[1]
 | 
						|
rmi $1==4	| |	remove(ALL)
 | 
						|
			"call .rmi4"		    | bx dx | |
 | 
						|
/*
 | 
						|
rmi !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .rmi" erase(%[1])     |	    | |
 | 
						|
*/
 | 
						|
#ifdef LONGEMPAT
 | 
						|
loc loc cii rmi loc loc cii $1==2 && $2==4 && $4==4 && $5==4 && $6==2
 | 
						|
		| rm-ACC-DXREG X_ACC X_DXREG |
 | 
						|
			"idiv %[1]"
 | 
						|
			erase(%[2]) erase(%[3])        | dx | |(2,171)+%[1]
 | 
						|
#endif
 | 
						|
ngi $1==2	| X_REG |
 | 
						|
			"neg %[1]"
 | 
						|
			setcc(%[1]) erase(%[1])     | %[1]  | |(2,3)
 | 
						|
ngi $1==4	| X_REG X_REG |
 | 
						|
			"neg %[2]"
 | 
						|
			"neg %[1]"
 | 
						|
			"sbb %[2],0"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | | (8,10)
 | 
						|
...		| X_REG-ACC X_ACC |
 | 
						|
			"neg %[2]"
 | 
						|
			"neg %[1]"
 | 
						|
			"sbb %[2],0"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | | (7,10)
 | 
						|
/*
 | 
						|
ngi !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ngi"		    |	    | |
 | 
						|
*/
 | 
						|
loc sli $1==1 && $2==2 | X_REG |
 | 
						|
			"sal %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | | (2,2)
 | 
						|
sli $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"sal %[2],cl"
 | 
						|
			setcc(%[2]) erase(%[2])     | %[2]  | | (2,8)
 | 
						|
sli $1==4	| X_CXREG X_REG X_REG |
 | 
						|
			"jcxz 1f"
 | 
						|
			"2: sal %[2],1"
 | 
						|
			"rcl %[3],1"
 | 
						|
			"loop 2b\n1:"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						| %[3] %[2] | |
 | 
						|
/*
 | 
						|
sli !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sli"		    |	    | |
 | 
						|
*/
 | 
						|
loc sri $1==1 && $2==2 | X_REG |
 | 
						|
			"sar %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | | (2,2)
 | 
						|
sri $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"sar %[2],cl"
 | 
						|
			setcc(%[2]) erase(%[2])     | %[2]  | | (2,8)
 | 
						|
sri $1==4	| X_CXREG X_REG X_REG |
 | 
						|
			"jcxz 1f"
 | 
						|
			"2: sar %[3],1"
 | 
						|
			"rcr %[2],1"
 | 
						|
			"loop 2b\n1:"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						| %[3] %[2] | |
 | 
						|
/*
 | 
						|
sri !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sri"		    |	    | |
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
/************************************************
 | 
						|
 * Group 4 : unsigned arithmetic		*
 | 
						|
 *						*
 | 
						|
 * adu = adi					*
 | 
						|
 * sbu = sbi					*
 | 
						|
 * slu = sli					*
 | 
						|
 * mlu = mli					*
 | 
						|
 *						*
 | 
						|
 * Supported : 2- and 4 byte arithmetic.	*
 | 
						|
 ************************************************/
 | 
						|
 | 
						|
adu		| |	|				    | adi $1 |
 | 
						|
sbu		| |	|				    | sbi $1 |
 | 
						|
mlu		| |	|				    | mli $1 |
 | 
						|
dvu $1==2	| rm-ACC X_ACC |
 | 
						|
			allocate(%[1],DXREG={ANYCON,0})
 | 
						|
			"div %[1]"
 | 
						|
			erase(%[2]) erase(%[a])      | %[2] | |(2,149)+%[1]
 | 
						|
dvu $1==4	| |	remove(ALL)
 | 
						|
			"call .dvu4"		    | cx ax | |
 | 
						|
/*
 | 
						|
dvu !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dvu" erase(%[1])     |	    | |
 | 
						|
*/
 | 
						|
rmu $1==2	| rm-ACC X_ACC |
 | 
						|
			allocate(%[1],DXREG={ANYCON,0})
 | 
						|
			"div %[1]"
 | 
						|
			erase(%[2]) erase(%[a])        | dx | |(3,149)+%[1]
 | 
						|
rmu $1==4	| |	remove(ALL)
 | 
						|
			"call .rmu4"		    | bx dx | |
 | 
						|
/*
 | 
						|
rmu !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .rmu" erase(%[1])     |	    | |
 | 
						|
*/
 | 
						|
slu		| |	|				    | sli $1 |
 | 
						|
loc sru $1==1 && $2==2 | X_REG |
 | 
						|
			"shr %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | | (2,2)
 | 
						|
sru $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"shr %[2],cl"
 | 
						|
			setcc(%[2]) erase(%[2])      | %[2] | | (2,8)
 | 
						|
sru $1==4	| X_CXREG X_REG X_REG |
 | 
						|
			"jcxz 1f" /* result => samecc */
 | 
						|
			"2: shr %[3],1"
 | 
						|
			"rcr %[2],1"
 | 
						|
			"loop 2b\n1:"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						| %[3] %[2] | |
 | 
						|
/*
 | 
						|
sru !defined($1)| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sru"		    |	    | |
 | 
						|
*/
 | 
						|
 | 
						|
/************************************************
 | 
						|
 * Group 5 : Floating point arithmetic		*
 | 
						|
 *						*
 | 
						|
 ************************************************/
 | 
						|
 | 
						|
adf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .adf4"		    |	    | |
 | 
						|
adf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .adf8"		    |	    | |
 | 
						|
adf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .adf" erase(%[1])	    |	    | |
 | 
						|
sbf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sbf4"		    |	    | |
 | 
						|
sbf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sbf8"		    |	    | |
 | 
						|
sbf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sbf" erase(%[1])	    |	    | |
 | 
						|
mlf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mlf4"		    |	    | |
 | 
						|
mlf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mlf8"		    |	    | |
 | 
						|
mlf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mlf" erase(%[1])	    |	    | |
 | 
						|
dvf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dvf4"		    |	    | |
 | 
						|
dvf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dvf8"		    |	    | |
 | 
						|
dvf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dvf" erase(%[1])	    |	    | |
 | 
						|
ngf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ngf4"		    |	    | |
 | 
						|
ngf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ngf8"		    |	    | |
 | 
						|
ngf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ngf" erase(%[1])	    |	    | |
 | 
						|
fif $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fif4"		    |	    | |
 | 
						|
fif $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fif8"		    |	    | |
 | 
						|
fif !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fif" erase(%[1])	    |	    | |
 | 
						|
fef $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fef4"		    |	    | |
 | 
						|
fef $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fef8"		    |	    | |
 | 
						|
fef !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .fef" erase(%[1])	    |	    | |
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 6 : pointer arithmetic.	*
 | 
						|
 *					*
 | 
						|
 * Pointers have size 2 bytes.		*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
adp $1==1	| nocoercions : reg_off | |
 | 
						|
			  {reg_off, %[1.reg],%[1.off]+"+"+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN | |
 | 
						|
			       {ADDR_EXTERN, %[1.off]+"+"+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_LOCAL | |
 | 
						|
					     {ADDR_LOCAL, %[1.ind]+$1 } | |
 | 
						|
...		| nocoercions : bpreg_off | |
 | 
						|
				     {bpreg_off, %[1.reg], %[1.ind]+$1} | |
 | 
						|
...		| X_REG |
 | 
						|
			"inc %[1]"
 | 
						|
			erase(%[1]) setcc(%[1])   | %[1]	| | (1,2)
 | 
						|
adp $1 == 0-1	| nocoercions : reg_off | |
 | 
						|
			      {reg_off, %[1.reg],%[1.off]+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN | |
 | 
						|
				   {ADDR_EXTERN, %[1.off]+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_LOCAL| |{ADDR_LOCAL, %[1.ind]+$1 } | |
 | 
						|
...		| nocoercions : bpreg_off | |
 | 
						|
				     {bpreg_off, %[1.reg], %[1.ind]+$1} | |
 | 
						|
...		| X_REG |
 | 
						|
			"dec %[1]"
 | 
						|
			erase(%[1]) setcc(%[1])   | %[1]	| | (1,2)
 | 
						|
adp		| nocoercions : reg_off | |
 | 
						|
			  {reg_off, %[1.reg],%[1.off]+"+"+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_EXTERN | |
 | 
						|
			       {ADDR_EXTERN, %[1.off]+"+"+tostring($1)} | |
 | 
						|
...		| nocoercions : ADDR_LOCAL | |
 | 
						|
					     {ADDR_LOCAL, %[1.ind]+$1 } | |
 | 
						|
...		| nocoercions : bpreg_off | |
 | 
						|
				     {bpreg_off, %[1.reg], %[1.ind]+$1} | |
 | 
						|
...		| X_ADDREG | |		  {reg_off, %[1], tostring($1)} | |
 | 
						|
...		| nocoercions : X_ACC + X_CXREG + X_DXREG |
 | 
						|
			"add %[1],$1"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]  | | (4,4)
 | 
						|
ads $1==2	| nocoercions : ANYCON reg_off |  |
 | 
						|
			{reg_off, %[2.reg],
 | 
						|
				%[2.off]+"+"+tostring(%[1.val])}	| |
 | 
						|
...		| nocoercions : ADDR_EXTERN reg_off | |
 | 
						|
			{reg_off, %[2.reg], %[2.off]+"+"+%[1.off]}	| |
 | 
						|
...		| rm reg_off |
 | 
						|
			"add %[2.reg],%[1]"
 | 
						|
			erase(%[2.reg]) setcc(%[2.reg]) |
 | 
						|
			  {reg_off, %[2.reg], %[2.off]} | | (2,3) + %[1]
 | 
						|
...		| nocoercions : ANYCON bpreg_off | |
 | 
						|
			      {bpreg_off, %[2.reg], %[2.ind]+%[1.val]} | |
 | 
						|
...		| rm bpreg_off |
 | 
						|
			"add %[2.reg],%[1]"
 | 
						|
			erase(%[2.reg]) setcc(%[2.reg]) |
 | 
						|
			{bpreg_off, %[2.reg], %[2.ind]} | | (2,3) + %[1]
 | 
						|
...		| reg_off rmorconst |
 | 
						|
			"add %[1.reg],%[2]"
 | 
						|
			erase(%[1.reg]) setcc(%[1.reg]) |
 | 
						|
			  {reg_off, %[1.reg], %[1.off]} | | (2,3) + %[2]
 | 
						|
...		| bpreg_off rmorconst |
 | 
						|
			"add %[1.reg],%[2]"
 | 
						|
			erase(%[1.reg]) setcc(%[1.reg]) |
 | 
						|
			{bpreg_off, %[1.reg], %[1.ind]} | | (2,3) + %[2]
 | 
						|
...		| nocoercions : reg_off ANYCON |  |
 | 
						|
			{reg_off, %[1.reg],
 | 
						|
				  %[1.off]+"+"+tostring(%[2.val])}     | |
 | 
						|
...		| nocoercions : reg_off ADDR_EXTERN | |
 | 
						|
			    {reg_off, %[1.reg], %[1.off]+"+"+%[2.off]} | |
 | 
						|
...		| nocoercions : reg_off reg_off |
 | 
						|
			"add %[1.reg],%[2.reg]"
 | 
						|
			erase(%[1.reg]) setcc(%[1.reg]) |
 | 
						|
	       {reg_off,%[1.reg],%[1.off]+"+"+%[2.off]} | | (2,3)
 | 
						|
...		| IREG ADDR_LOCAL |	  | {bpreg_off,%[1],%[2.ind]} | |
 | 
						|
/*
 | 
						|
...		| (REG-IREG) ADDR_LOCAL |
 | 
						|
			allocate(%[1],ADDREG=%[1])
 | 
						|
			"add %[a],bp"
 | 
						|
		  | {reg_off, %[a], tostring(%[2.ind])} | | (2,3)
 | 
						|
*/
 | 
						|
#ifdef DEEPER
 | 
						|
...		| X_REG rmorconst |
 | 
						|
			"add %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| rmorconst X_REG |
 | 
						|
			"add %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"add %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"add %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
#else
 | 
						|
...		| X_ADDREG ADDR_EXTERN | |      {reg_off, %[1], %[2.off]} | |
 | 
						|
...		| X_ADDREG rm |
 | 
						|
			"add %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| ADDR_EXTERN X_ADDREG | |      {reg_off, %[2], %[1.off]} | |
 | 
						|
...		| rm X_ADDREG |
 | 
						|
			"add %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
#endif
 | 
						|
sbs $1==2	| nocoercions : ANYCON reg_off |   |
 | 
						|
		   {reg_off, %[2.reg], %[2.off]+"-"+tostring(%[1.val])} | |
 | 
						|
...		| nocoercions : ANYCON ADDR_LOCAL | |
 | 
						|
					{ADDR_LOCAL, %[2.ind]-%[1.val]} | |
 | 
						|
...		| rm reg_off |
 | 
						|
			"sub %[2.reg],%[1]"
 | 
						|
			erase(%[2.reg]) setcc(%[2.reg]) |
 | 
						|
					  {reg_off, %[2.reg], %[2.off]} | |
 | 
						|
/*	Should not occur
 | 
						|
...		| nocoercions : reg_off ANYCON |   |
 | 
						|
		   {reg_off, %[1.reg], %[1.off]+"-"+tostring(%[2.val])} | |
 | 
						|
...		| ANYCON ADDR_EXTERN | |
 | 
						|
			 {ADDR_EXTERN, %[2.off]+"+"+tostring(%[1.val])} | |
 | 
						|
...		| nocoercions : ANYCON ADDR_LOCAL | |
 | 
						|
				        {ADDR_LOCAL, %[1.val]+%[2.ind]} | |
 | 
						|
*/
 | 
						|
...		| rm X_REG |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| const X_ACC |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 7 : increment/decrement/zero	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
inc		| X_REG |
 | 
						|
			"inc %[1]"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(1,2)
 | 
						|
inl		| |	remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"inc $1(bp)"
 | 
						|
			setcc({LOCAL2,$1,2})	     |	    | |(3,24)
 | 
						|
ine		| |	remove(indirects)
 | 
						|
			"inc ($1)"
 | 
						|
			setcc({EXTERN2,$1})	     |	    | |(4,21)
 | 
						|
dec		| X_REG |
 | 
						|
			"dec %[1]"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(1,2)
 | 
						|
del		| |	remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"dec $1(bp)"
 | 
						|
			setcc({LOCAL2,$1,2})	     |	    | |(3,24)
 | 
						|
dee		| |	remove(indirects)
 | 
						|
			"dec ($1)"
 | 
						|
			setcc({EXTERN2,$1})	     |	    | |(4,21)
 | 
						|
zrl		| |	remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			move({ANYCON,0},{LOCAL2,$1,2})
 | 
						|
						     |	    | |
 | 
						|
zre		| |	remove(indirects)
 | 
						|
			move({ANYCON,0},{EXTERN2,$1})|	    | |
 | 
						|
zrf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .zrf4"		    |	    | |
 | 
						|
zrf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .zrf8"		    |	    | |
 | 
						|
zrf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .zrf" erase(%[1])	    |	    | |
 | 
						|
zer $1==2	| |			       | {ANYCON,0} | |
 | 
						|
zer $1==4	| |		    | {ANYCON,0} {ANYCON,0} | |
 | 
						|
zer $1==6	| |		    | {ANYCON,0} {ANYCON,0}
 | 
						|
						 {ANYCON,0} | |
 | 
						|
zer $1==8	| |		    | {ANYCON,0} {ANYCON,0}
 | 
						|
				      {ANYCON,0} {ANYCON,0} | |
 | 
						|
zer defined($1) | |	remove(ALL)
 | 
						|
			move({ANYCON,$1/2},cx)
 | 
						|
			move({ANYCON,0},bx)
 | 
						|
			"1: push bx"
 | 
						|
			"loop 1b"
 | 
						|
			samecc erase(cx)		  | | |(3,10+$1*4)
 | 
						|
zer !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			move({ANYCON,0},bx)
 | 
						|
			"sar cx,1"
 | 
						|
			"1:\tpush bx"
 | 
						|
			"loop 1b"
 | 
						|
			samecc erase(%[1])		  | | |
 | 
						|
 | 
						|
lol adi stl $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"add $1(bp),%[1]"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol ngi stl $1==$3 && $2==2 | |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"neg $1(bp)"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol ads stl $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"add $1(bp),%[1]"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol adp stl $1==$3	    | |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"add $1(bp),$2"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol adp stl $1==$3 && $2==1 | |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"inc $1(bp)"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol adp stl $1==$3 && $2==0-1 | |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"dec $1(bp)"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol and stl $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"and $1(bp),%[1]"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol ior stl $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"or $1(bp),%[1]"
 | 
						|
			setcc({LOCAL2, $1, 2})		  | | |
 | 
						|
lol com stl $1==$3 && $2==2 | |
 | 
						|
			remove(indexed)
 | 
						|
			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | 
						|
			"not $1(bp)"
 | 
						|
			samecc				  | | |
 | 
						|
lil adi sil $1==$3 && $2==2 | regorconst |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"add (%[a]),%[1]"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil ngi sil $1==$3 && $2==2 | |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"neg (%[a])"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil ads sil $1==$3 && $2==2 | regorconst |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"add (%[a]),%[1]"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil adp sil $1==$3	    | |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"add (%[a]),$2"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil adp sil $1==$3 && $2==1 | |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"inc (%[a])"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil adp sil $1==$3 && $2==0-1 | |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"dec (%[a])"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil and sil $1==$3 && $2==2 | regorconst |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"and (%[a]),%[1]"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil ior sil $1==$3 && $2==2 | regorconst |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"or (%[a]),%[1]"
 | 
						|
			setcc({ind_reg2, %[a]})		  | | |
 | 
						|
lil com sil $1==$3 && $2==2 | |
 | 
						|
			allocate(ADDREG={LOCAL2, $1, 2})
 | 
						|
			remove(referals)
 | 
						|
			"not (%[a])"
 | 
						|
			samecc				  | | |
 | 
						|
loe adi ste $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			"add ($1),%[1]"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe ngi ste $1==$3 && $2==2 | |
 | 
						|
			remove(indirects)
 | 
						|
			"neg ($1)"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe ads ste $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			"add ($1),%[1]"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe adp ste $1==$3 	    | |
 | 
						|
			remove(indirects)
 | 
						|
			"add ($1),$2"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe adp ste $1==$3 && $2==1 | |
 | 
						|
			remove(indirects)
 | 
						|
			"inc ($1)"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe adp ste $1==$3 && $2==0-1 | |
 | 
						|
			remove(indirects)
 | 
						|
			"dec ($1)"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe and ste $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			"and ($1),%[1]"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe ior ste $1==$3 && $2==2 | regorconst |
 | 
						|
			remove(indirects)
 | 
						|
			"or ($1),%[1]"
 | 
						|
			setcc({EXTERN2, $1})		  | | |
 | 
						|
loe com ste $1==$3 && $2==2 | |
 | 
						|
			remove(indirects)
 | 
						|
			"not ($1)"
 | 
						|
			samecc				  | | |
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 8 : Convert instructions	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
cii		| CXREG DXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cii"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
ciu		| |		|			| cuu	|
 | 
						|
cui		| |		|			| cuu	|
 | 
						|
cuu		| CXREG BXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cuu"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cif		| CXREG DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cif"			  | | |
 | 
						|
cuf		| CXREG DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cuf"			  | | |
 | 
						|
cfi		| CXREG DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cfi"			  | | |
 | 
						|
cfu		| CXREG DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cfu"			  | | |
 | 
						|
cff		| CXREG DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cff"			  | | |
 | 
						|
loc loc cii $1==1 && $2==2	| ACC1 |
 | 
						|
			 allocate(%[1],ACC)
 | 
						|
			 "cbw"
 | 
						|
			 samecc 		    | %[a]  | |(1,2)
 | 
						|
loc loc cii $1==1 && $2==4	| ACC1 |
 | 
						|
			allocate(%[1],ACC,DXREG)
 | 
						|
			"cbw"
 | 
						|
			"cwd"
 | 
						|
			samecc			    | dx ax | |(2,7)
 | 
						|
loc loc cii $1==2 && $2==4	| ACC |
 | 
						|
			allocate(DXREG)
 | 
						|
			"cwd"
 | 
						|
			samecc			    | dx ax | |(1,5)
 | 
						|
loc loc cii $1==4 && $2==2	| a_word a_word |    | %[1] | |
 | 
						|
loc loc cuu $1==2 && $2==4	| a_word |
 | 
						|
			allocate(REG={ANYCON,0})| %[a] %[1] | |
 | 
						|
loc loc cuu $1==4 && $2==2	| a_word a_word |    | %[1] | |
 | 
						|
loc loc ciu $1==2 && $2==4	| a_word |
 | 
						|
			allocate(REG={ANYCON,0})| %[a] %[1] | |
 | 
						|
loc loc ciu $1==4 && $2==2	| a_word a_word |    | %[1] | |
 | 
						|
loc loc cui $1==2 && $2==4	| a_word |
 | 
						|
			allocate(REG={ANYCON,0})| %[a] %[1] | |
 | 
						|
loc loc cui $1==4 && $2==2	| a_word a_word |    | %[1] | |
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 9 : Logical instructions	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
and $1==2	| NO X_REG rmorconst |
 | 
						|
			"and %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| rmorconst X_REG |
 | 
						|
			"and %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"and %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"and %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
and $1==4	| NO X_REG X_REG rmorconst rmorconst |
 | 
						|
			"and %[1],%[3]"
 | 
						|
			"and %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(4,6)+%[4]+%[3]
 | 
						|
...		| X_ACC X_REG const rmorconst |
 | 
						|
			"and %[1],%[3]"
 | 
						|
			"and %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(5,7)+%[4]
 | 
						|
...		| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"and %[3],%[1]"
 | 
						|
			"and %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(4,6)+%[1]+%[2]
 | 
						|
...		| const rmorconst-ACC X_ACC X_REG |
 | 
						|
			"and %[3],%[1]"
 | 
						|
			"and %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(5,7)+%[2]
 | 
						|
and defined($1) | |	remove(ALL)
 | 
						|
			"mov cx,$1"
 | 
						|
			"call .and"			  | | |
 | 
						|
and !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .and"
 | 
						|
			erase(%[1])			  | | |
 | 
						|
ior $1==2	| X_REG rmorconst |
 | 
						|
			"or %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| NO rmorconst X_REG |
 | 
						|
			"or %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"or %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"or %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
ior $1==4	| NO X_REG X_REG rmorconst rmorconst |
 | 
						|
			"or %[1],%[3]"
 | 
						|
			"or %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(4,6)+%[4]+%[3]
 | 
						|
...		| X_ACC X_REG const rmorconst |
 | 
						|
			"or %[1],%[3]"
 | 
						|
			"or %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(5,7)+%[4]
 | 
						|
...		| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"or %[3],%[1]"
 | 
						|
			"or %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(4,6)+%[1]+%[2]
 | 
						|
...		| const rmorconst-ACC X_ACC X_REG |
 | 
						|
			"or %[3],%[1]"
 | 
						|
			"or %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(5,7)+%[2]
 | 
						|
ior defined($1) | |	remove(ALL)
 | 
						|
			"mov cx,$1"
 | 
						|
			"call .ior"			  | | |
 | 
						|
ior !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ior"
 | 
						|
			erase(%[1])			  | | |
 | 
						|
xor $1==2	| NO X_REG rmorconst |
 | 
						|
			"xor %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | 
						|
...		| rmorconst X_REG |
 | 
						|
			"xor %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"xor %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) | %[1]	| | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"xor %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) | %[2]	| | (3,4)
 | 
						|
xor $1==4	| NO X_REG X_REG rmorconst rmorconst |
 | 
						|
			"xor %[1],%[3]"
 | 
						|
			"xor %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(4,6)+%[4]+%[3]
 | 
						|
...		| X_ACC X_REG const rmorconst |
 | 
						|
			"xor %[1],%[3]"
 | 
						|
			"xor %[2],%[4]"
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(5,7)+%[4]
 | 
						|
...		| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"xor %[3],%[1]"
 | 
						|
			"xor %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(4,6)+%[1]+%[2]
 | 
						|
...		| const rmorconst-ACC X_ACC X_REG |
 | 
						|
			"xor %[3],%[1]"
 | 
						|
			"xor %[4],%[2]"
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						| %[4] %[3] | |(5,7)+%[2]
 | 
						|
xor defined($1) | |	remove(ALL)
 | 
						|
			"mov cx,$1"
 | 
						|
			"call .xor"			  | | |
 | 
						|
xor !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .xor"
 | 
						|
			erase(%[1])			  | | |
 | 
						|
com $1==2	| X_REG |
 | 
						|
			"not %[1]"
 | 
						|
			samecc erase(%[1])	    | %[1]  | |(2,3)
 | 
						|
com $1==4	| X_REG X_REG |
 | 
						|
			"not %[2]"
 | 
						|
			"not %[1]"
 | 
						|
			samecc erase(%[1]) erase(%[2])
 | 
						|
						| %[2] %[1] | |(4,6)
 | 
						|
com defined($1) | |	remove(ALL)
 | 
						|
			"mov cx,$1"
 | 
						|
			"call .com"			  | | |
 | 
						|
com !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .com"
 | 
						|
			erase(%[1])			  | | |
 | 
						|
loc rol $1==1 && $2==2 | X_REG |
 | 
						|
			"rol %[1],1"
 | 
						|
			samecc erase(%[1])	     | %[1] | | (2,2)
 | 
						|
rol $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"rol %[2],cl"
 | 
						|
			samecc erase(%[2])	     | %[2] | | (2,8)
 | 
						|
rol $1==4	| X_CXREG X_REG X_REG |
 | 
						|
			"jcxz 1f"
 | 
						|
			"2: sal %[2],1"
 | 
						|
			"rcl %[3],1"
 | 
						|
			"adc %[2],0"
 | 
						|
			"loop 2b\n1:"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						| %[3] %[2] | |
 | 
						|
/*
 | 
						|
rol !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .rol"		    |	    | |
 | 
						|
*/
 | 
						|
loc ror $1==1 && $2==2 | X_REG |
 | 
						|
			"ror %[1],1"
 | 
						|
			samecc erase(%[1])	     | %[1] | | (2,2)
 | 
						|
ror $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"ror %[2],cl"
 | 
						|
			samecc erase(%[2])	     | %[2] | | (2,8)
 | 
						|
ror $1==4	| X_CXREG X_REG X_REG |
 | 
						|
			"jcxz 1f"
 | 
						|
			"neg cx"
 | 
						|
			"add cx,32"
 | 
						|
			"2: sal %[2],1"
 | 
						|
			"rcl %[3],1"
 | 
						|
			"adc %[2],0"
 | 
						|
			"loop 2b\n1:"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						| %[3] %[2] | |
 | 
						|
/*
 | 
						|
ror !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .ror"		    |	    | |
 | 
						|
*/
 | 
						|
 | 
						|
/********************************
 | 
						|
 * Group 10 : Set instructions	*
 | 
						|
 ********************************/
 | 
						|
 | 
						|
inn $1==2	| SHIFT_CREG X_REG |
 | 
						|
			"shr %[2],cl"
 | 
						|
			"and %[2],1"
 | 
						|
			setcc(%[2]) erase(%[2])      | %[2] | |(6,13)
 | 
						|
...		| SHIFT_CREG X_ACC |
 | 
						|
			"shr %[2],cl"
 | 
						|
			"and %[2],1"
 | 
						|
			setcc(%[2]) erase(%[2])      | %[2] | |(5,13)
 | 
						|
loc inn $1==1 && $2==2 | X_REG |
 | 
						|
			"shr %[1],1"
 | 
						|
			"and %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(6,6)
 | 
						|
...		    | X_ACC |
 | 
						|
			"shr %[1],1"
 | 
						|
			"and %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(5,6)
 | 
						|
loc inn $1==0 && $2==2 | X_REG |
 | 
						|
			"and %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(6,6)
 | 
						|
...		    | X_ACC |
 | 
						|
			"and %[1],1"
 | 
						|
			setcc(%[1]) erase(%[1])      | %[1] | |(5,6)
 | 
						|
inn defined($1) | X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			move({ANYCON,$1},cx)
 | 
						|
			"call .inn"
 | 
						|
			erase(ax)		       | ax | |
 | 
						|
inn !defined($1)| CXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .inn"
 | 
						|
			erase(%[2])		       | ax | |
 | 
						|
loc inn zeq $2==2 | rm |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],%(1<<$1%)"
 | 
						|
			"je $3" 		       |    | |
 | 
						|
loc inn zne $2==2 | rm |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],%(1<<$1%)"
 | 
						|
			"jne $3"		       |    | |
 | 
						|
set $1==2	| SHIFT_CREG |
 | 
						|
			allocate(REG={ANYCON,1})
 | 
						|
			"shl %[a],cl"
 | 
						|
			setcc(%[a]) erase(%[a])        | %[a] | |
 | 
						|
set defined($1) | X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			move({ANYCON,$1},cx)
 | 
						|
			"call .set"
 | 
						|
			erase(%[1])		       |      | |
 | 
						|
set !defined($1)| CXREG X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .set"
 | 
						|
			erase(%[2])		       |      | |
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 11 : Array instructions	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
lae aar $2==2 && rom(1,3)==1 && rom(1,1)==0 | | | | ads 2 |
 | 
						|
lae aar $2==2 && rom(1,3)==1 && rom(1,1)!=0 | | | | adp 0-rom(1,1) ads 2 |
 | 
						|
lae aar $2==2 && rom(1,3)==2 && rom(1,1)==0 | X_ADDREG |
 | 
						|
			"sal %[1],1"
 | 
						|
			erase(%[1])	   | %[1] | ads 2 |
 | 
						|
lae aar $2==2 && rom(1,3)==2 && rom(1,1)!=0 | X_ADDREG |
 | 
						|
			"sal %[1],1"
 | 
						|
			erase(%[1])	   | %[1] | adp 0-2*rom(1,1) ads 2 |
 | 
						|
lae aar $2==2 && rom(1,3)==4 && rom(1,1)==0 | X_ADDREG |
 | 
						|
			"sal %[1],1"
 | 
						|
			"sal %[1],1"
 | 
						|
			erase(%[1])	   | %[1] | ads 2 |
 | 
						|
lae aar $2==2 && rom(1,3)==4 && rom(1,1)!=0 | X_ADDREG |
 | 
						|
			"sal %[1],1"
 | 
						|
			"sal %[1],1"
 | 
						|
			erase(%[1])	   | %[1] | adp 0-4*rom(1,1) ads 2 |
 | 
						|
lae aar $2==2 && rom(1,1)==0		    | X_ACC |
 | 
						|
			allocate(DXREG,REG={ANYCON,rom(1,3)})
 | 
						|
			"mul %[b]"
 | 
						|
			erase(%[1])	    | %[1] | ads 2 |
 | 
						|
lae aar $2==2 && defined(rom(1,1))	    | X_ACC |
 | 
						|
			allocate(DXREG,REG={ANYCON,rom(1,3)})
 | 
						|
			"mul %[b]"
 | 
						|
			erase(%[1])  | %[1] | adp 0-rom(1,1)*rom(1,3) ads 2 |
 | 
						|
aar $1==2	 | halfindir X_ACC X_ADDREG |
 | 
						|
			allocate(DXREG)
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			"mul 4+%[1]"
 | 
						|
			"add %[3],%[2]"
 | 
						|
			erase(%[2]) erase(%[3])
 | 
						|
					    | %[3] | |
 | 
						|
...		| ADDR_EXTERN X_ACC X_ADDREG |
 | 
						|
			allocate(DXREG)
 | 
						|
			"sub %[2],(%[1])"
 | 
						|
			"mul (4+%[1])"
 | 
						|
			"add %[3],%[2]"
 | 
						|
			erase(%[2]) erase(%[3])
 | 
						|
					    | %[3] | |
 | 
						|
lae sar defined(rom(1,3)) | |	|	| lae $1 aar $2 sti rom(1,3) |
 | 
						|
lae lar defined(rom(1,3)) | |	|	| lae $1 aar $2 loi rom(1,3) |
 | 
						|
aar !defined($1) | |	remove(ALL)
 | 
						|
			"call .iaar"	    | di | |
 | 
						|
sar $1==2	| X_SIREG X_ACC X_DIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .sar2"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						 | | |
 | 
						|
sar !defined($1) | |	remove(ALL)
 | 
						|
			"call .isar"	       | | |
 | 
						|
lar $1==2	| X_DIREG X_ACC X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .lar2"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
						 | | |
 | 
						|
lar !defined($1) | |	remove(ALL)
 | 
						|
			"call .ilar"	       | | |
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * group 12 : Compare instructions	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
cmi $1==2	| |	|				    | sbi 2  |
 | 
						|
cmi $1==4	| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"sub %[3],%[1]"
 | 
						|
			"sbb %[4],%[2]"
 | 
						|
			"jne 1f"
 | 
						|
			"and %[3],%[3]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[4]\n1: "
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						     | %[4] | |
 | 
						|
cmu $1==2	| |	|				    | cmp |
 | 
						|
cmu $1==4	| |	remove(ALL)
 | 
						|
			"call .cmu4"		       | ax | |
 | 
						|
cms $1==2	| NO X_REG rmorconst |
 | 
						|
			"sub %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) |      %[1] | | (2,3) + %[2]
 | 
						|
...		| rmorconst X_REG |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) |      %[2] | | (2,3) + %[1]
 | 
						|
...		| X_ACC const |
 | 
						|
			"sub %[1],%[2]"
 | 
						|
			erase(%[1]) setcc(%[1]) |      %[1] | | (3,4)
 | 
						|
...		| const X_ACC |
 | 
						|
			"sub %[2],%[1]"
 | 
						|
			erase(%[2]) setcc(%[2]) |      %[2] | | (3,4)
 | 
						|
cms $1==4	| rmorconst rmorconst X_REG X_REG |
 | 
						|
			"sub %[3],%[1]"
 | 
						|
			"sbb %[4],%[2]"
 | 
						|
			"jne 1f"
 | 
						|
			"or %[4],%[3]\n1: "
 | 
						|
			setcc(%[4]) erase(%[3]) erase(%[4])
 | 
						|
						     | %[4] | |
 | 
						|
...		| NO X_REG X_REG rmorconst rmorconst |
 | 
						|
			"sub %[1],%[3]"
 | 
						|
			"sbb %[2],%[4]"
 | 
						|
			"jne 1f"
 | 
						|
			"or %[2],%[1]\n1: "
 | 
						|
			setcc(%[2]) erase(%[1]) erase(%[2])
 | 
						|
						     | %[2] | |
 | 
						|
cms defined($1) | |	remove(ALL)
 | 
						|
			move({ANYCON,$1},cx)
 | 
						|
			"call .cms"
 | 
						|
			erase(cx)		       | cx | |
 | 
						|
cms !defined($1)| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cms"
 | 
						|
			erase(cx)		       | cx | |
 | 
						|
cmf $1==4	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cmf4"		    |	    | |
 | 
						|
cmf $1==8	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cmf8"		    |	    | |
 | 
						|
cmf !defined($1)	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .cmf" erase(%[1])	    |	    | |
 | 
						|
 | 
						|
/* The costs with cmp are the cost of the 8086 cmp instruction */
 | 
						|
cmp		| NO REG rmorconst |
 | 
						|
			allocate(REG = {ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 2f"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]"
 | 
						|
			"jmp 2f"
 | 
						|
			"1:\tdec %[a]\n2:"
 | 
						|
			setcc(%[a])
 | 
						|
			erase(%[a])		     | %[a] | |(4,4)
 | 
						|
...	       | rmorconst REG |
 | 
						|
			allocate(REG = {ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 2f"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]"
 | 
						|
			"jmp 2f"
 | 
						|
			"1:\tdec %[a]\n2:"
 | 
						|
			setcc(%[a])
 | 
						|
			erase(%[a])		     | %[a] | |(4,4)
 | 
						|
...	       | ACC const |
 | 
						|
			allocate(REG = {ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 2f"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]"
 | 
						|
			"jmp 2f"
 | 
						|
			"1:\tdec %[a]\n2:"
 | 
						|
			setcc(%[a])
 | 
						|
			erase(%[a])		     | %[a] | |(3,4)
 | 
						|
...	       | const ACC |
 | 
						|
			allocate(REG = {ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 2f"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]"
 | 
						|
			"jmp 2f"
 | 
						|
			"1:\tdec %[a]\n2:"
 | 
						|
			setcc(%[a])
 | 
						|
			erase(%[a])		     | %[a] | |(3,4)
 | 
						|
tlt		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"jge 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
tle		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"jg 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
teq		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
tne		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
tge		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"jl 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
tgt		| rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			test(%[1])
 | 
						|
			"jle 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
tlt ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"jge 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
tle ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"jg 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
teq ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"jne 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
tne ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"je 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
tge ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"jl 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
tgt ior $2==2	| rm X_REG |
 | 
						|
			test(%[1])
 | 
						|
			"jle 1f"
 | 
						|
			"or %[2],1\n1:"
 | 
						|
			erase(%[2])		     | %[2] | |
 | 
						|
cmi tlt ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jge 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cmi tle ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jg 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cmi teq ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cmi tne ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cmi tge ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jl 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
cmi tgt ior $1==2 && $3==2	| regorconst rm X_REG |
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jle 1f"
 | 
						|
			"or %[3],1\n1:"
 | 
						|
			erase(%[3])		     | %[3] | |
 | 
						|
/* The cmp instruction has a special form for comparing
 | 
						|
   a byte ( sign-extended ) to a word (e.g. a register)
 | 
						|
   The "cmp ax,0" and "cmp bx,0" instructions have widely different
 | 
						|
   encodings but take the same amount of time and space.
 | 
						|
   Conclusion, using the special instruction for comparing
 | 
						|
   constants with ax is only better when the constant is <-128 or >127.
 | 
						|
   This relatively rare event wasn't worth extra entries in this table.
 | 
						|
*/
 | 
						|
cmi tlt $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jge 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jle 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmi tle $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jg 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jl 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmi teq $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmi tne $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmi tge $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jl 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jg 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmi tgt $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jle 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jge 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp tlt 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jae 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jbe 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp tle 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"ja 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp teq 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp tne 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp tge 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jb 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"ja 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp tgt 	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jbe 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jae 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cms teq $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cms tne $1==2	| regorconst rm |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			allocate(REG={ANYCON,0})
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je 1f"
 | 
						|
			"inc %[a]\n1:"
 | 
						|
			erase(%[a])		     | %[a] | |
 | 
						|
cmp zlt 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jb $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"ja $2" 			  | | |
 | 
						|
cmp zle 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jbe $2"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jae $2"			  | | |
 | 
						|
cmp zeq 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je $2" 			  | | |
 | 
						|
cmp zne 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne $2"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne $2"			  | | |
 | 
						|
cmp zge 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jae $2"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jbe $2"			  | | |
 | 
						|
cmp zgt 	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"ja $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jb $2" 			  | | |
 | 
						|
cms zeq $1==2	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je $2"			  	  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je $2"			  	  | | |
 | 
						|
cms zne $1==2	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne $2" 			  | | |
 | 
						|
and zeq $1==2	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[2],%[1]"
 | 
						|
			"je $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],%[2]"
 | 
						|
			"je $2"				  | | |
 | 
						|
and zne $1==2	| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[2],%[1]"
 | 
						|
			"jne $2" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],%[2]"
 | 
						|
			"jne $2"			  | | |
 | 
						|
loc and zeq $1<256 && $1>=0 && $2==2		| nocoercions : rm1 + memory2 |
 | 
						|
			remove(ALL)
 | 
						|
			"testb %[1],$1"
 | 
						|
			"je $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| GENREG |
 | 
						|
			remove(ALL)
 | 
						|
			"testb %[1.1],$1"
 | 
						|
			"je $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| nocoercions : IREG |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],$1"
 | 
						|
			"je $3" 			  | | | (2,3) + %[1]
 | 
						|
loc and zne $1<256 && $1>=0 && $2==2		| nocoercions : rm1 + memory2 |
 | 
						|
			remove(ALL)
 | 
						|
			"testb %[1],$1"
 | 
						|
			"jne $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| GENREG |
 | 
						|
			remove(ALL)
 | 
						|
			"testb %[1.1],$1"
 | 
						|
			"jne $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| nocoercions : IREG |
 | 
						|
			remove(ALL)
 | 
						|
			"test %[1],$1"
 | 
						|
			"jne $3" 			  | | | (2,3) + %[1]
 | 
						|
loc beq $1<256 && $1>=0		 		| nocoercions : rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			"cmpb %[1],$1"
 | 
						|
			"je $2" 			  | | | (1,3) + %[1]
 | 
						|
...						| rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],$1"
 | 
						|
			"je $2" 			  | | | (2,3) + %[1]
 | 
						|
loc bne $1<256 && $1>=0		 		| nocoercions : rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			"cmpb %[1],$1"
 | 
						|
			"jne $2" 			  | | | (1,3) + %[1]
 | 
						|
...						| rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],$1"
 | 
						|
			"jne $2" 			  | | | (2,3) + %[1]
 | 
						|
/* Note: test for <,<=,>,>= can be done in this way,
 | 
						|
	 with use of the unsigned conditional jumps, jb, etc. */
 | 
						|
loc cmu zeq $1<256 && $1>=0 && $2==2		| nocoercions : rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			"cmpb %[1],$1"
 | 
						|
			"je $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],$1"
 | 
						|
			"je $3" 			  | | | (2,3) + %[1]
 | 
						|
loc cmu zne $1<256 && $1>=0 && $2==2		| nocoercions : rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			"cmpb %[1],$1"
 | 
						|
			"jne $3" 			  | | | (1,3) + %[1]
 | 
						|
...						| rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],$1"
 | 
						|
			"jne $3" 			  | | | (2,3) + %[1]
 | 
						|
 | 
						|
/****************************************
 | 
						|
 * Group 13 : Branch instructions	*
 | 
						|
 ****************************************/
 | 
						|
 | 
						|
bra		| |	remove(ALL)
 | 
						|
			"jmp $1"
 | 
						|
			samecc				  | | |
 | 
						|
blt		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jl $1" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jg $1" 			  | | |
 | 
						|
ble		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jle $1"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jge $1"			  | | |
 | 
						|
beq		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"je $1" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"je $1" 			  | | |
 | 
						|
bne		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jne $1"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jne $1"			  | | |
 | 
						|
bge		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jge $1"			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jle $1"			  | | |
 | 
						|
bgt		| regorconst rm |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[2],%[1]"
 | 
						|
			"jg $1" 			  | | |
 | 
						|
...		| NO rm regorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],%[2]"
 | 
						|
			"jl $1" 			  | | |
 | 
						|
zlt		| rm |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"jl $1" 			  | | |
 | 
						|
zle		| rm |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"jle $1"			  | | |
 | 
						|
zeq		| rm+rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"je $1" 			  | | |
 | 
						|
zne		| rm+rm1 |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"jne $1"			  | | |
 | 
						|
zge		| rm |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"jge $1"			  | | |
 | 
						|
zgt		| rm |
 | 
						|
			remove(ALL)
 | 
						|
			test(%[1])
 | 
						|
			"jg $1" 			  | | |
 | 
						|
 | 
						|
/************************************************
 | 
						|
 * group 14 : Procedure call instructions	*
 | 
						|
 ************************************************/
 | 
						|
 | 
						|
cal		| |	remove(ALL)
 | 
						|
			"call $1"			  | | |
 | 
						|
cai		| rm |	remove(ALL)
 | 
						|
			"call %[1]"			  | | |
 | 
						|
lfr $1==2	| |				       | ax | |
 | 
						|
lfr $1==4	| |				    | dx ax | |
 | 
						|
lfr $1==6	| |				 | bx dx ax | |
 | 
						|
lfr $1==8	| |			      | cx bx dx ax | |
 | 
						|
ret $1==0	| |	remove(ALL)
 | 
						|
			"mov sp,bp"
 | 
						|
			"pop bp"
 | 
						|
			"ret"				  | | |
 | 
						|
ret $1==2	| ACC |
 | 
						|
			"mov sp,bp"
 | 
						|
			"pop bp"
 | 
						|
			"ret"				  | | |
 | 
						|
ret $1==4	| ACC DXREG |
 | 
						|
			"mov sp,bp"
 | 
						|
			"pop bp"
 | 
						|
			"ret"				  | | |
 | 
						|
ret $1==6	| ACC DXREG BXREG |
 | 
						|
			"mov sp,bp"
 | 
						|
			"pop bp"
 | 
						|
			"ret"				  | | |
 | 
						|
ret $1==8	| ACC DXREG BXREG CXREG |
 | 
						|
			"mov sp,bp"
 | 
						|
			"pop bp"
 | 
						|
			"ret"				  | | |
 | 
						|
 | 
						|
/************************************************
 | 
						|
 * Group 15 : Miscellaneous instructions	*
 | 
						|
 ************************************************/
 | 
						|
 | 
						|
asp $1==2	| nocoercions : a_word |		  | | |
 | 
						|
...		| STACK |
 | 
						|
			allocate(IREG) /* GENREG may contain lfr area */
 | 
						|
			"pop %[a]" erase(%[a]) samecc	  | | | (1,8)
 | 
						|
asp $1==4	| nocoercions : a_word a_word | 	  | | |
 | 
						|
...		| STACK |
 | 
						|
			allocate(IREG) /* GENREG may contain lfr area */
 | 
						|
			"pop %[a]" "pop %[a]"
 | 
						|
			erase(%[a]) samecc		  | | | (2,16)
 | 
						|
asp $1==0-2	| |	/* Anything will do */	       | bp | |
 | 
						|
...		| |	remove(ALL)
 | 
						|
			"push lb"			  | | | (1,10)
 | 
						|
asp		| |	remove(ALL)
 | 
						|
			"add sp,$1"			  | | | (4,4)
 | 
						|
ass $1==2	| rmorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"add sp,%[1]"			  | | |
 | 
						|
ass !defined($1)| rm rmorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"add sp,%[2]"			  | | |
 | 
						|
blm $1==0	| |					  | | asp 4 |
 | 
						|
blm $1>0	| X_DIREG X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			allocate(CXREG={ANYCON,$1/2})
 | 
						|
			"rep movs"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[a])
 | 
						|
							  | | |
 | 
						|
bls $1==2	| X_CXREG X_DIREG X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"sar cx,1"
 | 
						|
			"rep movs"
 | 
						|
			erase(%[1]) erase(%[2]) erase(%[3])
 | 
						|
							  | | |
 | 
						|
bls !defined($1)| rm-CXREG-DIREG-SIREG X_CXREG X_DIREG X_SIREG |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"sar cx,1"
 | 
						|
			"rep movs"
 | 
						|
			erase(%[2]) erase(%[3]) erase(%[4])
 | 
						|
							  | | |
 | 
						|
csa $1==2	| X_SIREG X_BXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"jmp .csa2"
 | 
						|
			erase(%[1]) erase(%[2]) 	  | | |
 | 
						|
csa !defined($1)| rm-SIREG-BXREG X_SIREG X_BXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"jmp .csa2"
 | 
						|
			erase(%[2]) erase(%[3]) 	  | | |
 | 
						|
csb $1==2	| X_SIREG X_DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"jmp .csb2"
 | 
						|
			erase(%[1]) erase(%[2]) 	  | | |
 | 
						|
csb !defined($1)| rm-SIREG-DIREG X_SIREG X_DXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"jmp .csb2"
 | 
						|
			erase(%[2]) erase(%[3]) 	  | | |
 | 
						|
dup $1==2	| REG |				| %[1] %[1] | |
 | 
						|
dup $1==4	| REG REG |	      | %[2] %[1] %[2] %[1] | |
 | 
						|
dup		| |	remove(ALL)
 | 
						|
			move({ANYCON, $1}, cx)
 | 
						|
			"call .dup"
 | 
						|
			erase(cx)			  | | |
 | 
						|
dus $1==2	| X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"call .dup"
 | 
						|
			erase(%[1])			  | | |
 | 
						|
dus !defined($1)| rm-CXREG X_CXREG |
 | 
						|
			remove(ALL)
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"call .dup"
 | 
						|
			erase(%[2])			  | | |
 | 
						|
exg $1==2	| a_word a_word |		| %[1] %[2] | |
 | 
						|
exg $1==4	| a_word a_word a_word a_word |
 | 
						|
				      | %[2] %[1] %[4] %[3] | |
 | 
						|
exg defined($1) | |	remove(ALL)
 | 
						|
			move({ANYCON,$1},cx)
 | 
						|
			"call .exg"
 | 
						|
			erase(cx)			  | | |
 | 
						|
exg		| rmorconst |
 | 
						|
			remove(ALL)
 | 
						|
			move(%[1],cx)
 | 
						|
			"call .exg"
 | 
						|
			erase(cx)			  | | |
 | 
						|
gto		| |	remove(ALL)
 | 
						|
			"mov bx,$1"
 | 
						|
			"jmp .gto"			  | | |
 | 
						|
fil		| |	"mov (hol0+4),$1"		  | | |
 | 
						|
lim		| |	allocate(REG)
 | 
						|
			"mov %[a],(.ignmask)"	     | %[a] | |
 | 
						|
lin		| |	"mov (hol0),$1" 		  | | |
 | 
						|
lni		| |	"inc (hol0)"			  | | |
 | 
						|
lor $1==0	| |				       | bp | |
 | 
						|
lor $1==1	| |	remove(ALL)
 | 
						|
			allocate(REG)
 | 
						|
			"mov %[a],sp"		     | %[a] | |
 | 
						|
lor $1==2	| |	allocate(REG)
 | 
						|
			"mov %[a],(.reghp)"	     | %[a] | |
 | 
						|
mon		| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .mon"			  | | |
 | 
						|
nop		| |	remove(ALL)
 | 
						|
			"call .nop"			  | | |
 | 
						|
rck $1==2	| SIREG ACC |
 | 
						|
			"call .rck"		       | ax | |
 | 
						|
rck !defined($1)| rm-SIREG-ACC SIREG ACC |
 | 
						|
			"cmp %[1],2"
 | 
						|
			"jne .unknown"
 | 
						|
			"call .rck"		       | ax | |
 | 
						|
rtt		| |		|			    | ret 0 |
 | 
						|
sig		| X_REG |
 | 
						|
			"xchg (.trppc),%[1]"
 | 
						|
			erase(%[1])		     | %[1] | |
 | 
						|
sim		| regorconst |
 | 
						|
			"mov (.ignmask),%[1]"		  | | |
 | 
						|
str $1==0	| rmorconst |
 | 
						|
			"mov bp,%[1]"			  | | |
 | 
						|
str $1==1	| rmorconst |
 | 
						|
			remove(ALL)
 | 
						|
			"mov sp,%[1]"			  | | |
 | 
						|
str $1==2	| |
 | 
						|
			remove(ALL)
 | 
						|
			"call .strhp"			  | | |
 | 
						|
trp		| X_ACC |
 | 
						|
			remove(ALL)
 | 
						|
			"call .trp"			  | | |
 | 
						|
 | 
						|
/********************************
 | 
						|
 * From source to register	*
 | 
						|
 ********************************/
 | 
						|
 | 
						|
| rmorconst  |	allocate(%[1],REG=%[1]) 	| %[a]	| |
 | 
						|
| reg_off |	"add %[1.reg],%[1.off]"
 | 
						|
		erase(%[1.reg]) setcc(%[1.reg]) 
 | 
						|
					    | %[1.reg]  | |(2,3) + %[1]
 | 
						|
#ifdef DEEPER
 | 
						|
| halfindir |
 | 
						|
		allocate(%[1],REG)
 | 
						|
		move(%[1],%[a])
 | 
						|
		samecc				| %[a]	| |(0,0)
 | 
						|
#else
 | 
						|
| halfindir |
 | 
						|
		allocate(%[1],ADDREG)
 | 
						|
		move(%[1],%[a])
 | 
						|
		samecc				| %[a]	| |(0,0)
 | 
						|
#endif
 | 
						|
 | 
						|
/********************************
 | 
						|
 * From source to token 	*
 | 
						|
 ********************************/
 | 
						|
 | 
						|
| ANYCON     |	     | {ADDR_EXTERN,tostring(%[1.val])} | |
 | 
						|
 | 
						|
/********************************
 | 
						|
 * From source1 		*
 | 
						|
 ********************************/
 | 
						|
 | 
						|
| rm1 | 	allocate(%[1],REG1=%[1])	| %[a]	| |
 | 
						|
| rm1 | 	allocate(%[1],GENREG)
 | 
						|
		move(%[1],%[a.1])
 | 
						|
		"xorb %[a.2],%[a.2]"		| %[a]	| |(2,3)
 | 
						|
| ACC1 |	allocate(%[1],ACC)
 | 
						|
		"xorb %[a.2],%[a.2]"		| %[a]	| |(2,3)
 | 
						|
/*
 | 
						|
| BLREG |	allocate(%[1],BXREG)
 | 
						|
		"xorb %[a.2],%[a.2]"		| %[a]	| |(2,3)
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/************************
 | 
						|
 * From STACK coercions *
 | 
						|
 ************************/
 | 
						|
 | 
						|
| STACK |	allocate(REG)
 | 
						|
		"pop %[a]"
 | 
						|
		samecc				| %[a]	| | (2,8)
 | 
						|
 | 
						|
MOVES:
 | 
						|
(ACC,		   EXTERN2,   "mov %[2],%[1]" samecc,	   (3,16))
 | 
						|
(ACC1,		   EXTERN1,   "movb %[2],%[1]" samecc,	   (3,16))
 | 
						|
(ACC,		   EXTERN1,   "movb %[2],%[1.1]" samecc,   (3,16))
 | 
						|
(EXTERN2,	   ACC,       "mov %[2],%[1]" samecc,	   (3,14))
 | 
						|
(EXTERN1,	   ACC1,      "movb %[2],%[1]" samecc,	   (3,14))
 | 
						|
(rm,		   REG,       "mov %[2],%[1]" samecc,	   (2,2) + %[1] )
 | 
						|
(anyreg,	   dest,      "mov %[2],%[1]" samecc,	   (2,3) + %[2] )
 | 
						|
(halfindir,	   REG,	      "lea %[2],%[1]" samecc,	   (2,3) + %[1] )
 | 
						|
(rm1,		   REG1,      "movb %[2],%[1]" samecc,	   (2,2) + %[1] )
 | 
						|
(REG1,		   rm1,       "movb %[2],%[1]" samecc,	   (2,3) + %[2] )
 | 
						|
(GENREG,	   rm1,       "movb %[2],%[1.1]" samecc,   (2,3) + %[2] )
 | 
						|
(ANYCON %[val]==0, REG,       "xor %[2],%[2]" setcc(%[2]), (2,3))
 | 
						|
(ANYCON %[val]==0, REG1,      "xorb %[2],%[2]" setcc(%[2]),(2,3))
 | 
						|
(const, 	   REG,       "mov %[2],%[1]" samecc,	   (3,4))
 | 
						|
(const, 	   REG1,      "movb %[2],%[1]" samecc,	   (2,4))
 | 
						|
(const, 	   dest,      "mov %[2],%[1]" samecc,	   (4,4) + %[2] )
 | 
						|
(const, 	   rm1,       "movb %[2],%[1]" samecc,	   (3,4) + %[2] )
 | 
						|
 | 
						|
TESTS:
 | 
						|
(anyreg,	"or %[1],%[1]", 	(2,3))
 | 
						|
(memory2,	"cmp %[1],0",		(3,11)+%[1])
 | 
						|
(REG1,		"orb %[1],%[1]", 	(2,3))
 | 
						|
(memory1,	"cmpb %[1],0",		(3,11)+%[1])
 | 
						|
 | 
						|
STACKS:
 | 
						|
(anyreg, ,	"push %[1]"
 | 
						|
		samecc			      ,  (1,10) )
 | 
						|
(memory2, ,	"push %[1]"
 | 
						|
		samecc			      ,  (2,10) + %[1] )
 | 
						|
(const, REG,	move(%[1],%[a])
 | 
						|
		"push %[a]"
 | 
						|
		samecc			      ,  (4,11) )
 | 
						|
(const, ,	".data\n1: .word %[1]\n.text"
 | 
						|
		"push (1b)"
 | 
						|
		samecc			      ,  (6,24) )
 | 
						|
(rm1, GENREG,	move({ANYCON,0},%[a])
 | 
						|
		move(%[1],%[a.1])
 | 
						|
		"push %[a]"
 | 
						|
		samecc			      ,  (2,10) + %[1] )
 | 
						|
(rm1, , 	"push %[1]"
 | 
						|
		"push si"
 | 
						|
		"mov si,sp"
 | 
						|
		"movb 3(si),0"
 | 
						|
		"pop si"
 | 
						|
		samecc			      ,  (10,60) + %[1] )
 | 
						|
(reg_off, ,	"add %[1.reg],%[1.off]"
 | 
						|
		"push %[1.reg]"
 | 
						|
		erase(%[1.reg])
 | 
						|
		setcc(%[1.reg])		      ,  ( 4,14) )
 | 
						|
(bpreg_off, ,	move(%[1],%[1.reg])
 | 
						|
		"push %[1.reg]"
 | 
						|
		samecc			      ,  ( 6,17) + %[1] )
 | 
						|
(ADDR_LOCAL %[ind]==0, ,
 | 
						|
		"push bp"
 | 
						|
		samecc			      ,  ( 1,10) )
 | 
						|
(halfindir, REG,move(%[1],%[a])
 | 
						|
		"push %[a]"
 | 
						|
		samecc			      ,  ( 6,17) + %[1] )
 | 
						|
(halfindir, ,	"push ax"
 | 
						|
		"push si"
 | 
						|
		"lea ax,%[1]"
 | 
						|
		"mov si,sp"
 | 
						|
		"xchg 2(si),ax"
 | 
						|
		"pop si"
 | 
						|
		samecc			      ,  (10,59) + %[1] )
 |