2361 lines
		
	
	
	
		
			63 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			2361 lines
		
	
	
	
		
			63 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} 			| |
 | |
| loe loe $1==$2	| | 	allocate(ADDREG={EXTERN2, $1})	| %[a] %[a]	| |
 | |
| lol lol $1==$2	| |	allocate(ADDREG={LOCAL2, $1, 2})| %[a] %[a]	| |
 | |
| 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			      | | |
 | |
| ...		| nocoercions : 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 */
 | |
| ...		| nocoercions: 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)
 | |
| ...		| X_ADDREG | |		  {reg_off, %[1], tostring($1)} | |
 | |
| 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)
 | |
| ...		| X_ADDREG | |		  {reg_off, %[1], tostring($1)} | |
 | |
| 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})		  | | |
 | |
| ldl adi sdl $1==$3 && $2==4 | regorconst regorconst |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+4 )
 | |
| 			"add $1(bp),%[1]"
 | |
| 			"adc %($1+2%)(bp),%[2]"		   | | |
 | |
| lol ngi stl $1==$3 && $2==2 | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			"neg $1(bp)"
 | |
| 			setcc({LOCAL2, $1, 2})		  | | |
 | |
| ldl ngi sdl $1==$3 && $2==4 | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+4 )
 | |
| 			"neg $1(bp)"
 | |
| 			"neg %($1+2%)(bp)"
 | |
| 			"sbb %($1+2%)(bp),0"		  | | |
 | |
| 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 lol adp stl $1==$2 && $1==$4 | |
 | |
| 			allocate(ADDREG={LOCAL2,$1,2})	  | %[a] | lol $2 adp $3 stl $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 adp stl $1==$3	    | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			"add $1(bp),$2"
 | |
| 			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 && $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 adp sil $1==$3	    | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"add (%[a]),$2"
 | |
| 			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})		  | | |
 | |
| lde adi sde $1==$3 && $2==4 | regorconst regorconst |
 | |
| 			remove(indirects)
 | |
| 			"add ($1),%[1]"
 | |
| 			"adc ($1+2),%[2]"		  | | |
 | |
| loe ngi ste $1==$3 && $2==2 | |
 | |
| 			remove(indirects)
 | |
| 			"neg ($1)"
 | |
| 			setcc({EXTERN2, $1})		  | | |
 | |
| lde ngi sde $1==$3 && $2==4 | |
 | |
| 			remove(indirects)
 | |
| 			"neg ($1)"
 | |
| 			"neg ($1+2)"
 | |
| 			"sbb ($1+2),0"			  | | |
 | |
| loe ads ste $1==$3 && $2==2 | regorconst |
 | |
| 			remove(indirects)
 | |
| 			"add ($1),%[1]"
 | |
| 			setcc({EXTERN2, $1})		  | | |
 | |
| loe loe adp ste $1==$4 && $1==$4 | |
 | |
| 			allocate(ADDREG={EXTERN2,$1})	| %[a] | loe $1 adp $3 ste $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 adp ste $1==$3 	    | |
 | |
| 			remove(indirects)
 | |
| 			"add ($1),$2"
 | |
| 			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	| ACC |
 | |
| 			 "cbw"
 | |
| 			 samecc 		    | ax  | |(1,2)
 | |
| ...				| ACC1 |
 | |
| 			 "cbw"
 | |
| 			 samecc			    | ax  | |(1,2)
 | |
| loc loc cii $1==1 && $2==4	| ACC |
 | |
| 			allocate(DXREG)
 | |
| 			"cbw"
 | |
| 			"cwd"
 | |
| 			samecc			    | dx ax | |(2,7)
 | |
| ...				| ACC1 |
 | |
| 			allocate(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 ciu	| |		|			| loc $1 loc $2 cuu |
 | |
| loc loc cui	| |		|			| loc $1 loc $2 cuu |
 | |
| loc loc cuu $1==$2		| |		|	|	|
 | |
| 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] | |
 | |
| 
 | |
| /****************************************
 | |
|  * 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] | |
 | |
| ...		| ACC1 |			| %[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] )
 |