2895 lines
		
	
	
	
		
			80 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			2895 lines
		
	
	
	
		
			80 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"
 | |
| 
 | |
| #define REGVARS
 | |
| 
 | |
| /********************************************************
 | |
|  * Back end tables for Intel 8086			*
 | |
|  * Author : Ed Keizer					*
 | |
|  * Added register variables: Ceriel Jacobs
 | |
|  *							*
 | |
|  * 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.
 | |
| cx	= ("cx", 2, cl, ch), REG, GENREG, CXREG, SHIFT_CREG.
 | |
| dx	= ("dx", 2, dl, dh), REG, GENREG, DXREG.
 | |
| bx	= ("bx", 2, bl, bh), REG, GENREG, BREG, BXREG, ADDREG.
 | |
| #ifdef REGVARS
 | |
| si	= ("si", 2) regvar, RREG, RADDREG.
 | |
| di	= ("di", 2) regvar, RREG, RADDREG.
 | |
| #else
 | |
| si	= ("si", 2), REG, IREG, SIREG, ADDREG.
 | |
| di	= ("di", 2), REG, IREG, DIREG, ADDREG.
 | |
| #endif
 | |
| 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)	 *
 | |
|  *****************************************/
 | |
| 
 | |
| Xreg_off    = { REGISTER reg; STRING off; } 2 cost=(1, 9) "%[off](%[reg])"
 | |
| Xbpreg_off  = { REGISTER reg; INT ind; }    2 cost=(1,11) "%[ind](bp)(%[reg])"
 | |
| Rreg_off    = { REGISTER reg; STRING off; } 2 cost=(1, 9) "%[off](%[reg])"
 | |
| Rbpreg_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
 | |
| #ifndef REGVARS
 | |
| X_SIREG 	= SIREG*SCRATCH
 | |
| X_DIREG 	= DIREG*SCRATCH
 | |
| #endif
 | |
| X_ADDREG	= ADDREG*SCRATCH
 | |
| 
 | |
| #ifdef REGVARS
 | |
| IREG		= RREG
 | |
| #endif
 | |
| 
 | |
| /* 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
 | |
| register	= REG
 | |
| #ifdef REGVARS
 | |
| 		  + RREG
 | |
| #endif
 | |
| anyreg		= register + BREG
 | |
| addreg		= ADDREG 
 | |
| #ifdef REGVARS
 | |
| 		  + RADDREG
 | |
| #endif
 | |
| rm		= anyreg + memory2
 | |
| rmnoacc		= RREG + BREG + CXREG + memory2
 | |
| rmorconst	= const + rm
 | |
| noregvar	= const + REG + BREG + memory2
 | |
| regorconst	= const + anyreg
 | |
| #ifdef REGVARS
 | |
| /* Needed because there is a shortage of ADDREG-registers.
 | |
|    This is the main penalty for having register variables.
 | |
| */
 | |
| regorconstnoaddr = const + RREG + ACC + CXREG + DXREG
 | |
| #else
 | |
| regorconstnoaddr = regorconst
 | |
| #endif
 | |
| dest		= register + 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 */
 | |
| reg_off		= Xreg_off + Rreg_off
 | |
| bpreg_off	= Xbpreg_off + Rbpreg_off
 | |
| halfindir	= reg_off + bpreg_off + ADDR_LOCAL
 | |
| a_word		= rmorconst + rm1 + halfindir
 | |
| no_reg_off	= rmorconst + rm1 + ADDR_LOCAL
 | |
| #ifdef REGVARS
 | |
| uses_bx		= ADDREG + Xreg_off + Xbpreg_off
 | |
| #endif
 | |
| 
 | |
| 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)}	| |
 | |
| #ifdef REGVARS
 | |
| lol inreg($1)==2 | |		| regvar($1)				| |
 | |
| #endif
 | |
| lol 		| |		| {LOCAL2, $1, 2}			| |
 | |
| loe		| |		| {EXTERN2, $1} 			| |
 | |
| loe loe $1==$2	| | 	allocate(REG={EXTERN2, $1})	| %[a] %[a]	| |
 | |
| #ifdef REGVARS
 | |
| lol lol $1==$2 && inreg($1)!=2
 | |
| 		| |	allocate(REG={LOCAL2, $1, 2})| %[a] %[a]	| |
 | |
| #else
 | |
| lol lol $1==$2	| |	allocate(REG={LOCAL2, $1, 2})| %[a] %[a]	| |
 | |
| #endif
 | |
| #ifdef REGVARS
 | |
| lil inreg($1)==2 | |		| {ind_reg2, regvar($1)}		| |
 | |
| #endif
 | |
| 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 })
 | |
| 				| {Xreg_off, %[a], SSL } 		| |
 | |
| lxa $1==2	| |	allocate(ADDREG={ind_regoff2, bp, SSL })
 | |
| 			move({ind_regoff2, %[a], SSL }, %[a])
 | |
| 				| {Xreg_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])
 | |
| 				| {Xreg_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	| noregvar |
 | |
| 			remove(ALL)
 | |
| 			allocate(CXREG={ANYCON,$1/2})
 | |
| 			"mov ax,si"
 | |
| 			"mov bx,di"
 | |
| 			"mov si,%[1]"
 | |
| 			"sub sp,%($1%)"
 | |
| 			"mov di,sp"
 | |
| 			"rep movs"
 | |
| 			"mov si,ax"
 | |
| 			"mov di,bx"
 | |
| 			erase(%[a])  | | | (16,16+$1*9)
 | |
| WRONG! */
 | |
| loi $1>4	| X_BXREG |
 | |
| 			remove(ALL)
 | |
| 			allocate(CXREG={ANYCON,$1})
 | |
| 			"call .loi"
 | |
| 			erase(%[a]) erase(%[1]) | | | (3,40+$1*9)
 | |
| los $1==2	| X_CXREG X_BXREG |
 | |
| 			remove(ALL)
 | |
| 			"call .los"
 | |
| 			erase(%[1]) erase(%[2]) 		|	| |
 | |
| los !defined($1)| rm X_CXREG X_BXREG |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],2"
 | |
| 			"jne .unknown"
 | |
| 			"call .los"
 | |
| 			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.	*
 | |
|  ****************************************************************/
 | |
| 
 | |
| #ifdef REGVARS
 | |
| stl inreg($1)==2
 | |
| 		| rmorconst |
 | |
| 			remove(regvar($1))
 | |
| 			move(%[1], regvar($1))			|	| |
 | |
| ...		| nocoercions : STACK |
 | |
| 			remove(regvar($1))
 | |
| 			"pop %(regvar($1)%)" samecc		|  | |(1,8)
 | |
| #endif
 | |
| 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	| | |
 | |
| #ifdef REGVARS
 | |
| sil inreg($1)==2| regorconst |
 | |
| 			remove(referals)
 | |
| 			move(%[1],{ind_reg2, regvar($1)})			|	| |
 | |
| ...		| nocoercions : STACK |
 | |
| 			"pop (%(regvar($1)%))"	samecc		|  | |(2,26)
 | |
| #endif
 | |
| sil		| regorconstnoaddr |
 | |
| 			allocate(ADDREG={ind_regoff2, bp, tostring($1)})
 | |
| 			remove(referals)
 | |
| 			move(%[1], {ind_reg2, %[a]})		|	| |
 | |
| ...		| STACK |
 | |
| 			allocate(ADDREG={ind_regoff2, bp, tostring($1)})
 | |
| 			remove(referals)
 | |
| 			"pop (%[a])"	samecc			| | | (2,26)
 | |
| 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			      | | |
 | |
| ...		| nocoercions : 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],{LOCAL1, %[1.ind], 1})
 | |
| 								|	| |
 | |
| 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	| noregvar |
 | |
| 			remove(ALL)
 | |
| 			allocate(CXREG={ANYCON,$1/2})
 | |
| 			"mov ax,si"
 | |
| 			"mov bx,di"
 | |
| 			"mov si,sp"
 | |
| 			"mov di,%[1]"
 | |
| 			"rep movs"
 | |
| 			"mov sp,si"
 | |
| 			"mov si,ax"
 | |
| 			"mov di,bx"
 | |
| 			erase(%[a]) |	| | (14,12+$1*8)
 | |
| WRONG! */
 | |
| sti $1>4	| X_BXREG |
 | |
| 			remove(ALL)
 | |
| 			allocate(CXREG={ANYCON,$1})
 | |
| 			"call .sti"
 | |
| 			erase(%[a]) erase(%[1]) | | | (3,40+$1*9)
 | |
| /* 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_BXREG |
 | |
| 			remove(ALL)
 | |
| 			"call .sts"
 | |
| 			erase(%[1]) erase(%[2]) 		|	| |
 | |
| sdl		| regorconst regorconst  |  | %[2] %[1]  | stl $1 stl $1+2 |
 | |
| ...		| nocoercions: STACK |	| | stl $1 stl $1+2 |
 | |
| sde		| regorconst regorconst  |  | %[2] %[1]  | ste $1 ste $1+"+2" |
 | |
| ...		| nocoercions: STACK |	| | 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| rmnoacc rmorconst |
 | |
| 			allocate(%[2],ACC=%[2],DXREG)
 | |
| 			"mul %[1]"
 | |
| 			nocc erase(%[a])	    | ax  | |(2,118)+%[1]
 | |
| mli $1==4	| X_ACC X_DXREG |
 | |
| 			remove(ALL)
 | |
| 			"call .mli4"
 | |
| 			erase(ax) erase(dx) setcc(dx)    | dx ax | |
 | |
| /* Not now,
 | |
| mli !defined($1)| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .mli"		    |	    | |
 | |
| */
 | |
| dvi $1==2	| rmnoacc rmorconst |
 | |
| 			allocate(%[2], ACC=%[2], DXREG)
 | |
| 			"cwd"
 | |
| 			"idiv %[1]"
 | |
| 			erase(%[a])		       | ax | |(3,176)+%[1]
 | |
| dvi $1==4	| |	remove(ALL)
 | |
| 			"call .dvi4"		    | dx ax | |
 | |
| /*
 | |
| dvi !defined($1)| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .dvi" erase(%[1])     |	    | |
 | |
| */
 | |
| rmi $1==2	| rmnoacc rmorconst |
 | |
| 			allocate(%[2], ACC=%[2], DXREG)
 | |
| 			"cwd"
 | |
| 			"idiv %[1]"
 | |
| 			erase(%[a])		       | dx | |(3,176)+%[1]
 | |
| rmi $1==4	| |	remove(ALL)
 | |
| 			"call .rmi4"		    | dx ax | |
 | |
| /*
 | |
| rmi !defined($1)| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .rmi" erase(%[1])     |	    | |
 | |
| */
 | |
| 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)
 | |
| /*
 | |
| 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)
 | |
| loc sli $1==1 && $2==4 | X_REG X_REG |
 | |
| 			"sal %[1],1"
 | |
| 			"rcl %[2],1"
 | |
| 			erase(%[1]) erase(%[2])	    | %[2] %[1] | |
 | |
| loc sli $1==16 && $2==4 | rmorconst rmorconst | | %[1] {ANYCON, 0} | |
 | |
| 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)
 | |
| loc sri $1==1 && $2==4 | X_REG X_REG |
 | |
| 			"sar %[2],1"
 | |
| 			"rcr %[1],1"
 | |
| 			erase(%[1]) erase(%[2])	    | %[2] %[1] | |
 | |
| 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	| rmnoacc rmorconst |
 | |
| 			allocate(%[2],ACC=%[2],DXREG={ANYCON,0})
 | |
| 			"div %[1]"
 | |
| 			erase(%[b]) erase(%[a])      | ax | |(2,149)+%[1]
 | |
| dvu $1==4	| |	remove(ALL)
 | |
| 			"call .dvu4"		    | dx ax | |
 | |
| /*
 | |
| dvu !defined($1)| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .dvu" erase(%[1])     |	    | |
 | |
| */
 | |
| rmu $1==2	| rmnoacc rmorconst |
 | |
| 			allocate(%[2],ACC=%[2],DXREG={ANYCON,0})
 | |
| 			"div %[1]"
 | |
| 			erase(%[b]) erase(%[a])        | dx | |(3,149)+%[1]
 | |
| rmu $1==4	| |	remove(ALL)
 | |
| 			"call .rmu4"		    | dx ax | |
 | |
| /*
 | |
| rmu !defined($1)| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .rmu" erase(%[1])     |	    | |
 | |
| */
 | |
| slu		| |	|				    | sli $1 |
 | |
| loc slu		| |	|				    | loc $1 sli $2 |
 | |
| lol loc slu	| |	|				    | lol $1 loc $2 sli $3 |
 | |
| loc sru $1==1 && $2==2 | X_REG |
 | |
| 			"shr %[1],1"
 | |
| 			setcc(%[1]) erase(%[1])      | %[1] | | (2,2)
 | |
| loc sru $1==16 && $2==4 | rmorconst rmorconst | | {ANYCON, 0} %[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		*
 | |
|  *						*
 | |
|  ************************************************/
 | |
| 
 | |
| /* Floating point stuff
 | |
|  * Arithmetic instructions
 | |
|  */
 | |
|  
 | |
| adf $1==4	| | | | cal ".adf4" asp 4 |
 | |
| adf $1==8	| | | | cal ".adf8" asp 8 |
 | |
| sbf $1==4	| | | | cal ".sbf4" asp 4 |
 | |
| sbf $1==8	| | | | cal ".sbf8" asp 8 |
 | |
| mlf $1==4	| | | | cal ".mlf4" asp 4 |
 | |
| mlf $1==8	| | | | cal ".mlf8" asp 8 |
 | |
| dvf $1==4	| | | | cal ".dvf4" asp 4 |
 | |
| dvf $1==8	| | | | cal ".dvf8" asp 8 |
 | |
| ngf $1==4	| | | | cal ".ngf4" |
 | |
| ngf $1==8	| | | | cal ".ngf8" |
 | |
| fif $1==4	| | | | lor 1 cal ".fif4" asp 2 |
 | |
| fif $1==8	| | | | lor 1 cal ".fif8" asp 2 |
 | |
| fef $1==4	| | | | lor 1 adp 0-2 cal ".fef4" |
 | |
| fef $1==8	| | | | lor 1 adp 0-2 cal ".fef8" |
 | |
| 
 | |
| /****************************************
 | |
|  * Group 6 : pointer arithmetic.	*
 | |
|  *					*
 | |
|  * Pointers have size 2 bytes.		*
 | |
|  ****************************************/
 | |
| 
 | |
| adp $1==1	| nocoercions : Xreg_off | |
 | |
| 			  {Xreg_off, %[1.reg],%[1.off]+"+"+tostring($1)} | |
 | |
| ...		| nocoercions : Rreg_off | |
 | |
| 			  {Rreg_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 : Xbpreg_off | |
 | |
| 				     {Xbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| nocoercions : Rbpreg_off | |
 | |
| 				     {Rbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| X_REG |
 | |
| 			"inc %[1]"
 | |
| 			erase(%[1]) setcc(%[1])   | %[1]	| | (1,2)
 | |
| ...		| X_ADDREG | |	  {Xreg_off, %[1], tostring($1)} | |
 | |
| ...		| nocoercions : RADDREG | |  {Rreg_off, %[1], tostring($1)} | |
 | |
| adp $1 == 0-1	| nocoercions : Xreg_off | |
 | |
| 			      {Xreg_off, %[1.reg],%[1.off]+tostring($1)} | |
 | |
| ...		| nocoercions : Rreg_off | |
 | |
| 			      {Rreg_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 : Xbpreg_off | |
 | |
| 				     {Xbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| nocoercions : Rbpreg_off | |
 | |
| 				     {Rbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| X_REG |
 | |
| 			"dec %[1]"
 | |
| 			erase(%[1]) setcc(%[1])   | %[1]	| | (1,2)
 | |
| ...		| X_ADDREG | |	  {Xreg_off, %[1], tostring($1)} | |
 | |
| ...		| nocoercions : RADDREG | |  {Rreg_off, %[1], tostring($1)} | |
 | |
| adp		| nocoercions : Xreg_off | |
 | |
| 			  {Xreg_off, %[1.reg],%[1.off]+"+"+tostring($1)} | |
 | |
| ...		| nocoercions : Rreg_off | |
 | |
| 			  {Rreg_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 : Xbpreg_off | |
 | |
| 				     {Xbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| nocoercions : Rbpreg_off | |
 | |
| 				     {Rbpreg_off, %[1.reg], %[1.ind]+$1} | |
 | |
| ...		| X_ADDREG | |	  	  {Xreg_off, %[1], tostring($1)} | |
 | |
| ...		| nocoercions : RADDREG | |  {Rreg_off, %[1], tostring($1)} | |
 | |
| ...		| X_REG |
 | |
| 			"add %[1],$1"
 | |
| 			erase(%[1]) setcc(%[1]) | %[1]  | | (4,4)
 | |
| ads $1==2	| nocoercions : ANYCON Rreg_off |  |
 | |
| 			{Rreg_off, %[2.reg],
 | |
| 				%[2.off]+"+"+tostring(%[1.val])}	| |
 | |
| ...		| nocoercions : ADDR_EXTERN Rreg_off | |
 | |
| 			{Rreg_off, %[2.reg], %[2.off]+"+"+%[1.off]}	| |
 | |
| ...		| nocoercions : ANYCON Xreg_off |  |
 | |
| 			{Xreg_off, %[2.reg],
 | |
| 				%[2.off]+"+"+tostring(%[1.val])}	| |
 | |
| ...		| nocoercions : ADDR_EXTERN Xreg_off | |
 | |
| 			{Xreg_off, %[2.reg], %[2.off]+"+"+%[1.off]}	| |
 | |
| ...		| rm Xreg_off |
 | |
| 			"add %[2.reg],%[1]"
 | |
| 			erase(%[2.reg]) setcc(%[2.reg]) |
 | |
| 			  {Xreg_off, %[2.reg], %[2.off]} | | (2,3) + %[1]
 | |
| ...		| nocoercions : ANYCON Xbpreg_off | |
 | |
| 			      {Xbpreg_off, %[2.reg], %[2.ind]+%[1.val]} | |
 | |
| ...		| nocoercions : ANYCON Rbpreg_off | |
 | |
| 			      {Rbpreg_off, %[2.reg], %[2.ind]+%[1.val]} | |
 | |
| ...		| rm Xbpreg_off |
 | |
| 			"add %[2.reg],%[1]"
 | |
| 			erase(%[2.reg]) setcc(%[2.reg]) |
 | |
| 			{Xbpreg_off, %[2.reg], %[2.ind]} | | (2,3) + %[1]
 | |
| ...		| Xreg_off rmorconst |
 | |
| 			"add %[1.reg],%[2]"
 | |
| 			erase(%[1.reg]) setcc(%[1.reg]) |
 | |
| 			  {Xreg_off, %[1.reg], %[1.off]} | | (2,3) + %[2]
 | |
| ...		| Xbpreg_off rmorconst |
 | |
| 			"add %[1.reg],%[2]"
 | |
| 			erase(%[1.reg]) setcc(%[1.reg]) |
 | |
| 			{Xbpreg_off, %[1.reg], %[1.ind]} | | (2,3) + %[2]
 | |
| ...		| nocoercions : Xreg_off ANYCON |  |
 | |
| 			{Xreg_off, %[1.reg],
 | |
| 				  %[1.off]+"+"+tostring(%[2.val])}     | |
 | |
| ...		| nocoercions : Xreg_off ADDR_EXTERN | |
 | |
| 			    {Xreg_off, %[1.reg], %[1.off]+"+"+%[2.off]} | |
 | |
| ...		| nocoercions : Rreg_off ANYCON |  |
 | |
| 			{Rreg_off, %[1.reg],
 | |
| 				  %[1.off]+"+"+tostring(%[2.val])}     | |
 | |
| ...		| nocoercions : Rreg_off ADDR_EXTERN | |
 | |
| 			    {Rreg_off, %[1.reg], %[1.off]+"+"+%[2.off]} | |
 | |
| ...		| nocoercions : Xreg_off reg_off |
 | |
| 			"add %[1.reg],%[2.reg]"
 | |
| 			erase(%[1.reg]) setcc(%[1.reg]) |
 | |
| 	       {Xreg_off,%[1.reg],%[1.off]+"+"+%[2.off]} | | (2,3)
 | |
| #ifndef REGVARS
 | |
| ...		| 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)
 | |
| */
 | |
| #else
 | |
| ...		| nocoercions: RREG ADDR_LOCAL |	  |
 | |
| 			{Rbpreg_off,%[1],%[2.ind]} | |
 | |
| #endif
 | |
| #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 | |      {Xreg_off, %[1], %[2.off]} | |
 | |
| ...		| X_ADDREG rm |
 | |
| 			"add %[1],%[2]"
 | |
| 			erase(%[1]) setcc(%[1]) | %[1]	| | (2,3) + %[2]
 | |
| ...		| ADDR_EXTERN X_ADDREG | |      {Xreg_off, %[2], %[1.off]} | |
 | |
| ...		| rm X_ADDREG |
 | |
| 			"add %[2],%[1]"
 | |
| 			erase(%[2]) setcc(%[2]) | %[2]	| | (2,3) + %[1]
 | |
| #endif
 | |
| sbs $1==2	| nocoercions : ANYCON Xreg_off |   |
 | |
| 		   {Xreg_off, %[2.reg], %[2.off]+"-"+tostring(%[1.val])} | |
 | |
| ...		| nocoercions : ANYCON Rreg_off |   |
 | |
| 		   {Rreg_off, %[2.reg], %[2.off]+"-"+tostring(%[1.val])} | |
 | |
| ...		| nocoercions : ANYCON ADDR_LOCAL | |
 | |
| 					{ADDR_LOCAL, %[2.ind]-%[1.val]} | |
 | |
| ...		| rm Xreg_off |
 | |
| 			"sub %[2.reg],%[1]"
 | |
| 			erase(%[2.reg]) setcc(%[2.reg]) |
 | |
| 					  {Xreg_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)
 | |
| #ifdef REGVARS
 | |
| inl inreg($1)==2| |
 | |
| 			remove(regvar($1))
 | |
| 			"inc %(regvar($1)%)"
 | |
| 			erase(regvar($1)) setcc(regvar($1))	     |	    | |(1,2)
 | |
| #endif
 | |
| 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)
 | |
| #ifdef REGVARS
 | |
| del inreg($1)==2| |
 | |
| 			remove(regvar($1))
 | |
| 			"dec %(regvar($1)%)"
 | |
| 			erase(regvar($1)) setcc(regvar($1))	     |	    | |(1,2)
 | |
| #endif
 | |
| 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)
 | |
| #ifdef REGVARS
 | |
| zrl inreg($1)==2| |
 | |
| 			remove(regvar($1))
 | |
| 			move({ANYCON,0},regvar($1))
 | |
| 			erase(regvar($1)) 	|	| |
 | |
| #endif
 | |
| zrl		| |	remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			move({ANYCON,0},{LOCAL2,$1,2})
 | |
| 						     |	    | |
 | |
| zre		| |	remove(indirects)
 | |
| 			move({ANYCON,0},{EXTERN2,$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])		  | | |
 | |
| 
 | |
| #ifdef REGVARS
 | |
| lol adi stl $1==$3 && $2==2 && inreg($1)==2 | rmorconst |
 | |
| 			remove(regvar($1))
 | |
| 			"add %(regvar($1)%),%[1]"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		  | | |
 | |
| #endif
 | |
| 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]"		   | | |
 | |
| #ifdef REGVARS
 | |
| lol loc sbi stl $1==$4 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"sub %(regvar($1)%),$2"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		   | | |
 | |
| #endif
 | |
| lol loc sbi stl $1==$4 && $3==2 | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			"sub $1(bp),$2"
 | |
| 			setcc({LOCAL2, $1, 2})		  | | |
 | |
| #ifdef REGVARS
 | |
| lol loc sli stl $1==$4 && $2==1 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"sal %(regvar($1)%),1"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| lol loc sli stl $1==$4 && $2==2 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"sal %(regvar($1)%),1"
 | |
| 			"sal %(regvar($1)%),1"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| lol loc sli stl $1==$4 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			allocate(CXREG = {ANYCON, $2})
 | |
| 			"sal %(regvar($1)%),cl"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| lol loc sri stl $1==$4 && $2==1 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"sar %(regvar($1)%),1"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| lol loc sri stl $1==$4 && $2==2 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"sar %(regvar($1)%),1"
 | |
| 			"sar %(regvar($1)%),1"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| lol loc sri stl $1==$4 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			allocate(CXREG = {ANYCON, $2})
 | |
| 			"sar %(regvar($1)%),cl"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		| | |
 | |
| #endif
 | |
| #ifdef REGVARS
 | |
| lol ngi stl $1==$3 && $2==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"neg %(regvar($1)%)"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		  | | |
 | |
| #endif
 | |
| 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+2%)(bp)"
 | |
| 			"neg $1(bp)"
 | |
| 			"sbb %($1+2%)(bp),0"		  | | |
 | |
| lol ads stl $1==$3 && $2==2 | | | | lol $1 adi 2 stl $1 |
 | |
| #ifdef REGVARS
 | |
| lol lol adp stl $1==$2 && $1==$4 && inreg($1)==2 | |
 | |
| 			allocate(ADDREG=regvar($1))	| %[a] | lol $2 adp $3 stl $2 |
 | |
| lol inl $1==$2 && inreg($1)==2 | |
 | |
| 			allocate(REG=regvar($1))	  | %[a] | inl $1 |
 | |
| lol del $1==$2 && inreg($1)==2 | |
 | |
| 			allocate(REG=regvar($1))	  | %[a] | del $1 |
 | |
| #endif
 | |
| lol lol adp stl $1==$2 && $1==$4 | |
 | |
| 			allocate(ADDREG={LOCAL2,$1,2})	  | %[a] | lol $2 adp $3 stl $2 |
 | |
| lol inl $1==$2 | |	allocate(REG={LOCAL2,$1,2})	  | %[a] | inl $1 |
 | |
| lol del $1==$2 | |	allocate(REG={LOCAL2,$1,2})	  | %[a] | del $1 |
 | |
| lol adp stl $1==$3 && $2==1 | | | | inl $1 |
 | |
| lol adp stl $1==$3 && $2==0-1 | | | | del $1 |
 | |
| #ifdef REGVARS
 | |
| lol adp stl $1==$3 && inreg($1)==2    | |
 | |
| 			remove(regvar($1))
 | |
| 			"add %(regvar($1)%),$2"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		  | | |
 | |
| #endif
 | |
| lol adp stl $1==$3	    | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			"add $1(bp),$2"
 | |
| 			setcc({LOCAL2, $1, 2})		  | | |
 | |
| #ifdef REGVARS
 | |
| lol and stl $1==$3 && $2==2 && inreg($1)==2 | rmorconst |
 | |
| 			remove(regvar($1))
 | |
| 			"and %(regvar($1)%),%[1]"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		  | | |
 | |
| #endif
 | |
| 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})		  | | |
 | |
| #ifdef REGVARS
 | |
| lol ior stl $1==$3 && $2==2 && inreg($1)==2 | rmorconst |
 | |
| 			remove(regvar($1))
 | |
| 			"or %(regvar($1)%),%[1]"
 | |
| 			erase(regvar($1)) setcc(regvar($1))		  | | |
 | |
| #endif
 | |
| 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})		  | | |
 | |
| #ifdef REGVARS
 | |
| lol com stl $1==$3 && $2==2 && inreg($1)==2 | |
 | |
| 			remove(regvar($1))
 | |
| 			"not %(regvar($1)%)"
 | |
| 			erase(regvar($1)) samecc				  | | |
 | |
| #endif
 | |
| lol com stl $1==$3 && $2==2 | |
 | |
| 			remove(indexed)
 | |
| 			remove(locals, %[ind]>=$1 && %[ind]<$1+2 )
 | |
| 			"not $1(bp)"
 | |
| 			samecc				  | | |
 | |
| #ifdef REGVARS
 | |
| lil adi sil $1==$3 && $2==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"add (%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil adi sil $1==$3 && $2==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"add (%[a]),%[1]"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil ngi sil $1==$3 && $2==2 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"neg (%(regvar($1)%))"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| 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 | | | | lil $1 adi 2 sil $1 |
 | |
| #ifdef REGVARS
 | |
| lil adp sil $1==$3 && $2==1 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"inc (%(regvar($1)%))"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil adp sil $1==$3 && $2==1 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"inc (%[a])"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil adp sil $1==$3 && $2==0-1 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"dec (%(regvar($1)%))"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil adp sil $1==$3 && $2==0-1 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"dec (%[a])"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil adp sil $1==$3 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"add (%(regvar($1)%)),$2"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil adp sil $1==$3	    | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"add (%[a]),$2"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil and sil $1==$3 && $2==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"and (%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil and sil $1==$3 && $2==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"and (%[a]),%[1]"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil ior sil $1==$3 && $2==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"or (%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_reg2, regvar($1)})		  | | |
 | |
| #endif
 | |
| lil ior sil $1==$3 && $2==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"or (%[a]),%[1]"
 | |
| 			setcc({ind_reg2, %[a]})		  | | |
 | |
| #ifdef REGVARS
 | |
| lil com sil $1==$3 && $2==2 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"not (%(regvar($1)%))"
 | |
| 			samecc				  | | |
 | |
| #endif
 | |
| lil com sil $1==$3 && $2==2 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"not (%[a])"
 | |
| 			samecc				  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof adi lol stf $1==$4 && $2==$5 && $3==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"add $2(%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof adi lol stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"add $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)}) | | |
 | |
| #ifdef REGVARS
 | |
| lol lof ngi lol stf $1==$4 && $2==$5 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"neg $2(%(regvar($1)%))"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof ngi lol stf $1==$4 && $2==$5 && $3==2 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"neg $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| lol lof ads lol stf $1==$4 && $2==$5 && $3==2 | | | | lol $1 lof $2 adi 2 lol $1 stf $2 |
 | |
| #ifdef REGVARS
 | |
| lol lof adp lol stf $1==$4 && $2==$5 && $3==1 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"inc $2(%(regvar($1)%))"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof adp lol stf $1==$4 && $2==$5 && $2==1 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"inc $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof adp lol stf $1==$4 && $2==$5 && $3==0-1 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"dec $2(%(regvar($1)%))"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof adp lol stf $1==$4 && $2==$5 && $3==0-1 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"dec $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"add $2(%(regvar($1)%)),$3"
 | |
| 			setcc({ind_regoff2, regvar($1),tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof adp lol stf $1==$4 && $2==$5	    | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"add $2(%[a]),$3"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof and lol stf $1==$4 && $2==$5 && $3==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"and $2(%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof and lol stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"and $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof ior lol stf $1==$4 && $2==$5 && $3==2 && inreg($1)==2 | regorconst |
 | |
| 			remove(referals)
 | |
| 			"or $2(%(regvar($1)%)),%[1]"
 | |
| 			setcc({ind_regoff2, regvar($1), tostring($2)})  | | |
 | |
| #endif
 | |
| lol lof ior lol stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"or $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| #ifdef REGVARS
 | |
| lol lof com lol stf $1==$4 && $2==$5 && $3==2 && inreg($1)==2 | |
 | |
| 			remove(referals)
 | |
| 			"not $2(%(regvar($1)%))"
 | |
| 			samecc				  | | |
 | |
| #endif
 | |
| lol lof com lol stf $1==$4 && $2==$5 && $3==2 | |
 | |
| 			allocate(ADDREG={LOCAL2, $1, 2})
 | |
| 			remove(referals)
 | |
| 			"not $2(%[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+2)"
 | |
| 			"neg ($1)"
 | |
| 			"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 ine $1==$2 | |	allocate(REG={EXTERN2,$1})	| %[a] | ine $1 |
 | |
| loe dee $1==$2 | |	allocate(REG={EXTERN2,$1})	| %[a] | dee $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				  | | |
 | |
| loe lof adi loe stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"add $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)}) | | |
 | |
| loe lof ngi loe stf $1==$4 && $2==$5 && $3==2 | |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"neg $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof ads loe stf $1==$4 && $2==$5 && $3==2 | | | | loe $1 lof $2 adi 2 loe $1 stf $2 |
 | |
| loe lof adp loe stf $1==$4 && $2==$5 && $2==1 | |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"inc $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof adp loe stf $1==$4 && $2==$5 && $3==0-1 | |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"dec $2(%[a])"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof adp loe stf $1==$4 && $2==$5	    | |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"add $2(%[a]),$3"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof and loe stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"and $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof ior loe stf $1==$4 && $2==$5 && $3==2 | regorconstnoaddr |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"or $2(%[a]),%[1]"
 | |
| 			setcc({ind_regoff2, %[a], tostring($2)})  | | |
 | |
| loe lof com loe stf $1==$4 && $2==$5 && $3==2 | |
 | |
| 			allocate(ADDREG={EXTERN2, $1})
 | |
| 			remove(referals)
 | |
| 			"not $2(%[a])"
 | |
| 			samecc				  | | |
 | |
| 
 | |
| /****************************************
 | |
|  * Group 8 : Convert instructions	*
 | |
|  ****************************************/
 | |
| 
 | |
| cii		| CXREG DXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .cii"
 | |
| 			erase(%[3])		     | %[3] | |
 | |
| ciu		| |		|			| cuu	|
 | |
| cui		| |		|			| cuu	|
 | |
| cuu		| CXREG DXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .cuu"
 | |
| 			erase(%[3])		     | %[3] | |
 | |
| loc loc cii $1==1 && $2==2	| X_ACC |
 | |
| 			 "cbw"
 | |
| 			 samecc 		    | ax  | |(1,2)
 | |
| ...				| nocoercions: rmorconst1 |
 | |
| 			allocate(%[1], ACC1 = %[1])
 | |
| 			 "cbw"
 | |
| 			 samecc			    | ax  | |(1,2)
 | |
| loc loc cii $1==1 && $2==4	| X_ACC |
 | |
| 			allocate(DXREG)
 | |
| 			"cbw"
 | |
| 			"cwd"
 | |
| 			samecc			    | %[a] ax | |(2,7)
 | |
| ...				| nocoercions: rmorconst1 |
 | |
| 			allocate(%[1], ACC1 = %[1], DXREG)
 | |
| 			"cbw"
 | |
| 			"cwd"
 | |
| 			samecc			    | dx ax | |(2,7)
 | |
| loc loc cii $1==2 && $2==4	| ACC |
 | |
| 			allocate(DXREG)
 | |
| 			"cwd"
 | |
| 			samecc			    | %[a] 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 |	| {ANYCON,0} %[1] | |
 | |
| loc loc cuu $1==4 && $2==2	| a_word a_word |    | %[1] | |
 | |
| 
 | |
| /*
 | |
|  * Floating point stuff
 | |
|  * Conversion
 | |
|  */
 | |
| loc loc cif	$1==2 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cif4" |
 | |
| loc loc cif	$1==4 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cif4" asp 2 |
 | |
| loc loc cif	$1==2 && $2==8 | X_REG |
 | |
| 			remove(ALL)
 | |
| 			"push %[1]"
 | |
| 			"push %[1]"
 | |
| 			"push %[1]"
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cif8" |
 | |
| loc loc cif	$1==4 && $2==8 | X_REG X_REG |
 | |
| 			remove(ALL)
 | |
| 			"push %[1]"
 | |
| 			"push %[2]"
 | |
| 			"push %[1]"
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cif8" |
 | |
| loc loc cuf	$1==2 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cuf4" |
 | |
| loc loc cuf	$1==4 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cuf4" asp 2 |
 | |
| loc loc cuf	$1==2 && $2==8 | X_REG |
 | |
| 			remove(ALL)
 | |
| 			"push %[1]"
 | |
| 			"push %[1]"
 | |
| 			"push %[1]"
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cuf8" |
 | |
| loc loc cuf	$1==4 && $2==8 | X_REG X_REG |
 | |
| 			remove(ALL)
 | |
| 			"push %[1]"
 | |
| 			"push %[2]"
 | |
| 			"push %[1]"
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"		| | cal ".cuf8" |
 | |
| loc loc cfi	$1==4 && $2==2 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfi" asp 8 lfr 2 |
 | |
| loc loc cfi	$1==4 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfi" asp 4 |
 | |
| loc loc cfi	$1==8 && $2==2 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfi" asp 12 lfr 2 |
 | |
| loc loc cfi	$1==8 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfi" asp 8 |
 | |
| loc loc cfu	$1==4 && $2==2 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfu" asp 8 lfr 2 |
 | |
| loc loc cfu	$1==4 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfu" asp 4 |
 | |
| loc loc cfu	$1==8 && $2==2 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfu" asp 12 lfr 2 |
 | |
| loc loc cfu	$1==8 && $2==4 | |
 | |
| 			remove(ALL)
 | |
| 			"mov ax,$1"
 | |
| 			"push ax"
 | |
| 			"mov ax,$2"
 | |
| 			"push ax"		| | cal ".cfu" asp 8 |
 | |
| loc loc cff	$1==8 && $2==4 | |
 | |
| 			remove(ALL)		| | cal ".cff4" asp 4 |
 | |
| loc loc cff	$1==4 && $2==8 | X_REG X_REG |
 | |
| 			remove(ALL)
 | |
| 			allocate(REG)
 | |
| 			"xor %[a],%[a]"
 | |
| 			"push %[a]"
 | |
| 			"push %[a]"
 | |
| 			"push %[2]"
 | |
| 			"push %[1]"		| | cal ".cff8" |
 | |
| 
 | |
| /****************************************
 | |
|  * 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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]
 | |
| ...		| nocoercions: 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 STACK |
 | |
| 			"test %[1],%(1<<$1%)"
 | |
| 			"je $3" 		       |    | |
 | |
| loc inn zne $2==2 | rm STACK |
 | |
| 			"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 |
 | |
| loc sli ads $1==1 && $2==2 && $3==2 | X_ADDREG |
 | |
| 			"sal %[1],1"
 | |
| 			erase(%[1])     | %[1] | ads 2 |
 | |
| #ifdef REGVARS
 | |
| ...	| nocoercions: rmorconst-ADDREG uses_bx |
 | |
| 			allocate(%[2],REG=%[2],ADDREG=%[1])
 | |
| 			"sal %[b],1"
 | |
| 			erase(%[b])     | %[b] %[a] | ads 2 |
 | |
| #endif
 | |
| loc sli ads $1==2 && $2==2 && $3==2 | X_ADDREG |
 | |
| 			"sal %[1],1"
 | |
| 			"sal %[1],1"
 | |
| 			erase(%[1])     | %[1] | ads 2 |
 | |
| #ifdef REGVARS
 | |
| ...	| nocoercions: rmorconst-ADDREG uses_bx |
 | |
| 			allocate(%[2],REG=%[2],ADDREG=%[1])
 | |
| 			"sal %[b],1"
 | |
| 			"sal %[b],1"
 | |
| 			erase(%[b])     | %[b] %[a] | ads 2 |
 | |
| #endif
 | |
| loc sli ads $2==2 && $3==2 | X_ADDREG |
 | |
| 			allocate(CXREG={ANYCON, $1})
 | |
| 			"sal %[1],cl"
 | |
| 			erase(%[1])     | %[1] | ads 2 |
 | |
| #ifdef REGVARS
 | |
| ...	| nocoercions: rmorconst-(ADDREG+CXREG) uses_bx |
 | |
| 			allocate(%[2],REG=%[2],ADDREG=%[1],CXREG={ANYCON,$1})
 | |
| 			"sal %[b],cl"
 | |
| 			erase(%[b])     | %[b] %[a] | ads 2 |
 | |
| #endif
 | |
| 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"	    | bx | |
 | |
| sar $1==2	| X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .sar2"
 | |
| 			erase(%[1]) erase(%[2])
 | |
| 						 | | |
 | |
| sar !defined($1) | |	remove(ALL)
 | |
| 			"call .isar"	       | | |
 | |
| lar $1==2	| X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .lar2"
 | |
| 			erase(%[1]) erase(%[2])
 | |
| 						 | | |
 | |
| lar !defined($1) | |	remove(ALL)
 | |
| 			"call .ilar"	       | | |
 | |
| 
 | |
| /****************************************
 | |
|  * group 12 : Compare instructions	*
 | |
|  ****************************************/
 | |
| 
 | |
| cmi $1==2	| NO register rmorconst |
 | |
| 			allocate(REG = {ANYCON,0})
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"je 2f"
 | |
| 			"jl 1f"
 | |
| 			"inc %[a]"
 | |
| 			"jmp 2f"
 | |
| 			"1:\tdec %[a]\n2:"
 | |
| 			setcc(%[a])
 | |
| 			erase(%[a])		     | %[a] | |(4,4)
 | |
| ...	       | rmorconst register |
 | |
| 			allocate(REG = {ANYCON,0})
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"je 2f"
 | |
| 			"jl 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"
 | |
| 			"jl 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"
 | |
| 			"jl 1f"
 | |
| 			"inc %[a]"
 | |
| 			"jmp 2f"
 | |
| 			"1:\tdec %[a]\n2:"
 | |
| 			setcc(%[a])
 | |
| 			erase(%[a])		     | %[a] | |(3,4)
 | |
| cmi $1==4	| |	remove(ALL)
 | |
| 			"call .cmi4"			| ax | |
 | |
| 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]"
 | |
| 			"or %[4],%[3]"
 | |
| 			setcc(%[4]) erase(%[3]) erase(%[4])
 | |
| 						     | %[4] | |
 | |
| ...		| NO X_REG X_REG rmorconst rmorconst |
 | |
| 			"sub %[1],%[3]"
 | |
| 			"sbb %[2],%[4]"
 | |
| 			"or %[2],%[1]"
 | |
| 			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 | |
 | |
| 
 | |
| /*
 | |
|  * Floating point
 | |
|  * Comparision
 | |
|  */
 | |
| 
 | |
| cmf $1==4	| | remove(ALL) | | cal ".cmf4" asp 8 lfr 2 |
 | |
| cmf $1==8	| | remove(ALL) | | cal ".cmf8" asp 16 lfr 2 |
 | |
| /*
 | |
|  * Floating Point
 | |
|  * Zero Constants
 | |
|  */
 | |
| zrf		| | | | zer $1 |
 | |
| 
 | |
| /* The costs with cmp are the cost of the 8086 cmp instruction */
 | |
| cmp		| NO register 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 register |
 | |
| 			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 STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jb $2" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"ja $2" 			  | | |
 | |
| cmp zle 	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jbe $2"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jae $2"			  | | |
 | |
| cmp zeq 	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"je $2" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"je $2" 			  | | |
 | |
| cmp zne 	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jne $2"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jne $2"			  | | |
 | |
| cmp zge 	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jae $2"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jbe $2"			  | | |
 | |
| cmp zgt 	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"ja $2" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jb $2" 			  | | |
 | |
| cms zeq $1==2	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"je $2"			  	  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"je $2"			  	  | | |
 | |
| cms zne $1==2	| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jne $2" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jne $2" 			  | | |
 | |
| ldc cmi zlt highw(1)==0 && loww(1)==0 && $2==4 | rmorconst rmorconst |
 | |
|                                         | %[2] | zlt $3 |
 | |
| ldc cmi zge highw(1)==0 && loww(1)==0 && $2==4 | rmorconst rmorconst |
 | |
|                                         | %[2] | zge $3 |
 | |
| ldc cms zeq $2==4 && loww(1)==0 && highw(1)==0 | rmorconst X_REG |
 | |
|                         remove(ALL)
 | |
|                         "or %[2],%[1]"
 | |
|                         "je $3"                        |               | |
 | |
| ...						| X_REG rmorconst |
 | |
| 			remove(ALL)
 | |
| 			"or %[1],%[2]"
 | |
| 			"je $3"			|		| |
 | |
| ldc cms zne $2==4 && loww(1)==0 && highw(1)==0 | rmorconst X_REG |
 | |
|                         remove(ALL)
 | |
|                         "or %[2],%[1]"
 | |
|                         "jne $3"                        |               | |
 | |
| ...						| X_REG rmorconst |
 | |
| 			remove(ALL)
 | |
| 			"or %[1],%[2]"
 | |
| 			"jne $3"			|		| |
 | |
| ldc cms zeq $2==4       | rmorconst rmorconst |
 | |
|                         remove(ALL)
 | |
|                         "cmp %[1],%(loww(1)%)"
 | |
|                         "jne 1f"
 | |
|                         "cmp %[2],%(highw(1)%)"
 | |
|                         "je $3"
 | |
|                         "1:"                            |               | |
 | |
| ldc cms zne $2==4       | rmorconst rmorconst |
 | |
|                         remove(ALL)
 | |
|                         "cmp %[1],%(loww(1)%)"
 | |
|                         "jne $3"
 | |
|                         "cmp %[2],%(highw(1)%)"
 | |
|                         "jne $3"                        |               | |
 | |
| cms zne $1==4	| regorconst regorconst rm rm STACK |
 | |
| 			"cmp %[3],%[1]"
 | |
| 			"jne $2"
 | |
| 			"cmp %[4],%[2]"
 | |
| 			"jne $2"			  | | |
 | |
| ...		| NO rm rm regorconst regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[3]"
 | |
| 			"jne $2"
 | |
| 			"cmp %[2],%[4]"
 | |
| 			"jne $2"			  | | |
 | |
| cms zeq $1==4	| regorconst regorconst rm rm STACK |
 | |
| 			"cmp %[3],%[1]"
 | |
| 			"jne 1f"
 | |
| 			"cmp %[4],%[2]"
 | |
| 			"je $2\n1:"			  | | |
 | |
| ...		| NO rm rm regorconst regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[3]"
 | |
| 			"jne 1f"
 | |
| 			"cmp %[2],%[4]"
 | |
| 			"je $2\n1:"			  | | |
 | |
| and zeq $1==2	| regorconst rm STACK |
 | |
| 			"test %[2],%[1]"
 | |
| 			"je $2" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"test %[1],%[2]"
 | |
| 			"je $2"				  | | |
 | |
| and zne $1==2	| regorconst rm STACK |
 | |
| 			"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 STACK |
 | |
| 			"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 STACK |
 | |
| 			"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 STACK |
 | |
| 			"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 STACK |
 | |
| 			"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 STACK |
 | |
| 			"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 STACK |
 | |
| 			"cmp %[1],$1"
 | |
| 			"jne $3" 			  | | | (2,3) + %[1]
 | |
| 
 | |
| /****************************************
 | |
|  * Group 13 : Branch instructions	*
 | |
|  ****************************************/
 | |
| 
 | |
| bra		| |	remove(ALL)
 | |
| 			"jmp $1"
 | |
| 			samecc				  | | |
 | |
| blt		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jl $1" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jg $1" 			  | | |
 | |
| ble		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jle $1"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jge $1"			  | | |
 | |
| beq		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"je $1" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"je $1" 			  | | |
 | |
| bne		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jne $1"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jne $1"			  | | |
 | |
| bge		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jge $1"			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jle $1"			  | | |
 | |
| bgt		| regorconst rm STACK |
 | |
| 			"cmp %[2],%[1]"
 | |
| 			"jg $1" 			  | | |
 | |
| ...		| NO rm regorconst |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],%[2]"
 | |
| 			"jl $1" 			  | | |
 | |
| zlt		| rm STACK |
 | |
| 			test(%[1])
 | |
| 			"jl $1" 			  | | |
 | |
| zle		| rm STACK |
 | |
| 			test(%[1])
 | |
| 			"jle $1"			  | | |
 | |
| zeq		| rm+rm1 STACK |
 | |
| 			test(%[1])
 | |
| 			"je $1" 			  | | |
 | |
| zne		| rm+rm1 STACK |
 | |
| 			test(%[1])
 | |
| 			"jne $1"			  | | |
 | |
| zge		| rm STACK |
 | |
| 			test(%[1])
 | |
| 			"jge $1"			  | | |
 | |
| zgt		| rm STACK |
 | |
| 			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	| | 	remove(ALL)
 | |
| 			"call .lfr6"			  | | |
 | |
| lfr $1==8	| |	remove(ALL)
 | |
| 			"call .lfr8"			  | | |
 | |
| ret $1==0	| |	remove(ALL)
 | |
| #ifdef REGVARS
 | |
| 			return
 | |
| #else
 | |
| 			"mov sp,bp"
 | |
| 			"pop bp"
 | |
| 			"ret"				 
 | |
| #endif
 | |
| 							| | |
 | |
| ret $1==2	| ACC |
 | |
| 			remove(ALL)
 | |
| #ifdef REGVARS
 | |
| 			return
 | |
| #else
 | |
| 			"mov sp,bp"
 | |
| 			"pop bp"
 | |
| 			"ret"
 | |
| #endif
 | |
| 							| | |
 | |
| ret $1==4	| ACC DXREG |
 | |
| 			remove(ALL)
 | |
| #ifdef REGVARS
 | |
| 			return
 | |
| #else
 | |
| 			"mov sp,bp"
 | |
| 			"pop bp"
 | |
| 			"ret"
 | |
| #endif
 | |
| 							| | |
 | |
| ret $1==6	| STACK |
 | |
| 			"call .ret6"
 | |
| #ifdef REGVARS
 | |
| 			return
 | |
| #else
 | |
| 			"mov sp,bp"
 | |
| 			"pop bp"
 | |
| 			"ret"
 | |
| #endif
 | |
| 							| | |
 | |
| ret $1==8	| STACK |
 | |
| 			"call .ret8"
 | |
| #ifdef REGVARS
 | |
| 			return
 | |
| #else
 | |
| 			"mov sp,bp"
 | |
| 			"pop bp"
 | |
| 			"ret"
 | |
| #endif
 | |
| 							| | |
 | |
| 
 | |
| /************************************************
 | |
|  * Group 15 : Miscellaneous instructions	*
 | |
|  ************************************************/
 | |
| 
 | |
| asp $1==2	| nocoercions : a_word |		  | | |
 | |
| ...		| STACK |
 | |
| 			allocate(BXREG)
 | |
| 			"pop %[a]" erase(%[a]) samecc	  | | | (1,8)
 | |
| asp $1==4	| nocoercions : a_word a_word | 	  | | |
 | |
| ...		| STACK |
 | |
| 			allocate(BXREG)
 | |
| 			"pop %[a]" "pop %[a]"
 | |
| 			erase(%[a]) samecc		  | | | (2,16)
 | |
| asp $1==0-2	| |	/* Anything will do */	       | bp | |
 | |
| asp		| STACK |
 | |
| 			"add sp,$1"			  | | | (4,4)
 | |
| ass $1==2	| rmorconst STACK |
 | |
| 			"add sp,%[1]"			  | | |
 | |
| ass !defined($1)| rm rmorconst STACK |
 | |
| 			"cmp %[1],2"
 | |
| 			"jne .unknown"
 | |
| 			"add sp,%[2]"			  | | |
 | |
| blm $1==0	| |					  | | asp 4 |
 | |
| blm $1>0	| |
 | |
| 			remove(ALL)
 | |
| 			allocate(CXREG={ANYCON,$1/2})
 | |
| 			"call .blm"
 | |
| 			erase(%[a])
 | |
| 							  | | |
 | |
| bls $1==2	| X_CXREG |
 | |
| 			remove(ALL)
 | |
| 			"sar cx,1"
 | |
| 			"call .blm"
 | |
| 			erase(%[1])
 | |
| 							  | | |
 | |
| bls !defined($1)| rm-CXREG X_CXREG |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],2"
 | |
| 			"jne .unknown"
 | |
| 			"sar cx,1"
 | |
| 			"call .blm"
 | |
| 			erase(%[2])
 | |
| 							  | | |
 | |
| csa $1==2	| X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"jmp .csa2"
 | |
| 			erase(%[1]) erase(%[2]) 	  | | |
 | |
| csa !defined($1)| rm-BXREG-ACC X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],2"
 | |
| 			"jne .unknown"
 | |
| 			"jmp .csa2"
 | |
| 			erase(%[2]) erase(%[3]) 	  | | |
 | |
| csb $1==2	| X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"jmp .csb2"
 | |
| 			erase(%[1]) erase(%[2]) 	  | | |
 | |
| csb !defined($1)| rm-BXREG-ACC X_BXREG X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"cmp %[1],2"
 | |
| 			"jne .unknown"
 | |
| 			"jmp .csb2"
 | |
| 			erase(%[2]) erase(%[3]) 	  | | |
 | |
| dup $1==2	| regorconst |				| %[1] %[1] | |
 | |
| ...		| ACC1 |			| %[1] %[1] | |
 | |
| dup $1==4	| regorconst regorconst |	      | %[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	| STACK |
 | |
| 			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	| BXREG ACC |
 | |
| 			"call .rck"		       | ax | |
 | |
| rck !defined($1)| rm-BXREG-ACC BXREG 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 STACK |
 | |
| 			"mov sp,%[1]"			  | | |
 | |
| str $1==2	| |
 | |
| 			remove(ALL)
 | |
| 			"call .strhp"			  | | |
 | |
| trp		| X_ACC |
 | |
| 			remove(ALL)
 | |
| 			"call .Xtrp"			  | | |
 | |
| 
 | |
| /********************************
 | |
|  * From source to register	*
 | |
|  ********************************/
 | |
| 
 | |
| | rmorconst  |	allocate(%[1],REG=%[1]) 	| %[a]	| |
 | |
| | Xreg_off |	"add %[1.reg],%[1.off]"
 | |
| 		erase(%[1.reg]) setcc(%[1.reg]) 
 | |
| 					    | %[1.reg]  | |(2,3) + %[1]
 | |
| | halfindir |
 | |
| 		allocate(%[1],REG)
 | |
| 		move(%[1],%[a])
 | |
| 		samecc				| %[a]	| |(0,0)
 | |
| | halfindir |
 | |
| 		allocate(%[1],ADDREG)
 | |
| 		move(%[1],%[a])
 | |
| 		samecc				| %[a]	| |(0,0)
 | |
| 
 | |
| /********************************
 | |
|  * 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,		   register,  "mov %[2],%[1]" samecc,	   (2,2) + %[1] )
 | |
| (anyreg,	   dest,      "mov %[2],%[1]" samecc,	   (2,3) + %[2] )
 | |
| (halfindir,	   register,  "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, register,  "xor %[2],%[2]" setcc(%[2]), (2,3))
 | |
| (ANYCON %[val]==0, REG1,      "xorb %[2],%[2]" setcc(%[2]),(2,3))
 | |
| (const, 	   register,  "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, ,	".sect .data\n1: .data2 %[1]\n.sect .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] )
 | |
| (Xreg_off, ,	"add %[1.reg],%[1.off]"
 | |
| 		"push %[1.reg]"
 | |
| 		erase(%[1.reg])
 | |
| 		setcc(%[1.reg])		      ,  ( 4,14) )
 | |
| (Xbpreg_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] )
 |