2963 lines
		
	
	
	
		
			77 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			2963 lines
		
	
	
	
		
			77 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /*
 | |
|  * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | |
|  * See the copyright notice in the ACK home directory, in the file "Copyright".
 | |
|  */
 | |
| 
 | |
| rscid = "$Id$"
 | |
| 
 | |
| /*
 | |
|  * Back end tables for Intel 80386
 | |
|  *
 | |
|  * Author : Ceriel J.H. Jacobs
 | |
|  *
 | |
|  * Partly adapted from Intel 8086 table
 | |
|  *
 | |
|  * wordsize = 4 bytes, pointersize = 4 bytes.
 | |
|  *
 | |
|  * Register ebp is used as LB, esp is used for SP.
 | |
|  * Some global variables are used:
 | |
|  * - .reghp	: the heap pointer
 | |
|  * - .ignmask	: trap ignore mask
 | |
|  * - .trppc	: address of user defined trap handler
 | |
|  *
 | |
|  */
 | |
| 
 | |
| #define WS 4
 | |
| #define PS 4
 | |
| 
 | |
| SL = 8
 | |
| SSL = "8"
 | |
| 
 | |
| EM_WSIZE = WS
 | |
| EM_PSIZE = PS
 | |
| EM_BSIZE = 8
 | |
| 
 | |
| SIZEFACTOR = 5/1
 | |
| 
 | |
| #define REGVARS
 | |
| 
 | |
| #define EXACT exact	/* to improve code but slow down code generator,
 | |
| 			   define it to nothing
 | |
| 			*/
 | |
| 
 | |
| /*****************************************************************/
 | |
| PROPERTIES
 | |
| /*****************************************************************/
 | |
| 
 | |
| REG1			/* general 1 byte register */
 | |
| REG2			/* general 2 byte register */
 | |
| ACC1			/* 1 byte accumulator */
 | |
| ACC2			/* 2 byte accumulator */
 | |
| REG			/* allocatable register */
 | |
| GENREG			/* register with sub-registers */
 | |
| ACC			/* accumulator */
 | |
| SHIFT_CREG		/* shift count register */
 | |
| BXREG			/* ebx register */
 | |
| AREG			/* address register */
 | |
| ADDREG			/* allocatable address register */
 | |
| CXREG			/* ecx register */
 | |
| DXREG			/* edx register */
 | |
| IREG			/* index register */
 | |
| RREG			/* register variable, or register without subregs */
 | |
| 
 | |
| /*****************************************************************/
 | |
| REGISTERS
 | |
| /*****************************************************************/
 | |
| 
 | |
| al				    : REG1 , ACC1 .
 | |
| ah,bl, bh, ch,dl,dh		    : REG1 .
 | |
| cl				    : REG1 , SHIFT_CREG .
 | |
| ax = al + ah			    : REG2 , ACC2 .
 | |
| bx = bl + bh			    : REG2 .
 | |
| cx = cl + ch			    : REG2 .
 | |
| dx = dl + dh			    : REG2 .
 | |
| eax = al + ah			    : REG, GENREG, IREG, ACC, ADDREG, AREG.
 | |
| ebx = bl + bh			    : REG, GENREG, IREG, BXREG, ADDREG, AREG.
 | |
| ecx = cl + ch			    : REG, GENREG, IREG, CXREG, SHIFT_CREG, ADDREG , AREG .
 | |
| edx = dl + dh			    : REG, GENREG, IREG, DXREG, ADDREG, AREG .
 | |
| #ifndef REGVARS
 | |
| esi				    : REG, RREG, IREG, AREG, ADDREG .
 | |
| edi				    : REG, RREG, IREG, AREG, ADDREG .
 | |
| #else
 | |
| esi				    : AREG , IREG , RREG regvar(reg_any) .
 | |
| edi				    : AREG , IREG , RREG regvar(reg_any) .
 | |
| #endif
 | |
| ebp				    : AREG , IREG .
 | |
| esp				    : AREG .
 | |
| 
 | |
| /*****************************************************************/
 | |
| TOKENS
 | |
| /*****************************************************************/
 | |
| 
 | |
| ANYCON		= { INT val; }	    4 cost(4,0) val .
 | |
| CONSTR		= { ADDR off; }	    4 cost(4,0) off .
 | |
| ADDR_EXTERN	= { ADDR off; }	    4 cost(4,0) off .
 | |
| EXTERN1		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
 | |
| EXTERN2		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
 | |
| EXTERN		= { ADDR off; }	    4 cost(4,5) "(" off ")" .
 | |
| ADDR_LOCAL	= { INT ind; }	    4 cost(1,0) ind "(ebp)" .
 | |
| LOCAL		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
 | |
| LOCAL1		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
 | |
| LOCAL2		= { INT ind; INT size; } 4 cost(1,5) ind "(ebp)" .
 | |
| 
 | |
| Rreg_off	= { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
 | |
| Xreg_off	= { AREG reg; ADDR off;} 4 cost(4,0) off "(" reg ")" .
 | |
| indexed_r_off	= { AREG reg; IREG reg2; INT scale; ADDR off;}
 | |
| 			4 cost(5,0) off "(" reg ")" "(" reg2 "*" scale ")" .
 | |
| indexed_off	= { IREG reg; INT scale; ADDR off;}
 | |
| 			4 cost(5,0) off "(" reg "*" scale ")" .
 | |
| 
 | |
| indir_r		= { AREG reg;} 4 cost(0,5) "(" reg ")" .
 | |
| indir_r1	= { AREG reg;} 4 cost(0,5) "(" reg ")" .
 | |
| indir_r2	= { AREG reg;} 4 cost(0,5) "(" reg ")" .
 | |
| indir_r_off	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
 | |
| indir_r_off1	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
 | |
| indir_r_off2	= { AREG reg; ADDR off;} 4 cost(4,5) off "(" reg ")" .
 | |
| 
 | |
| indir_indexed_r_off =
 | |
| 		  { AREG reg; IREG reg2; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
 | |
| indir_indexed_r_off1 =
 | |
| 		  { AREG reg; IREG reg2; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
 | |
| indir_indexed_r_off2 =
 | |
| 		  { AREG reg; IREG reg2; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg ")" "(" reg2 "*" scale ")" .
 | |
| indir_indexed_off =
 | |
| 		  { IREG reg; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg "*" scale ")" .
 | |
| indir_indexed_off1 =
 | |
| 		  { IREG reg; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg "*" scale ")" .
 | |
| indir_indexed_off2 =
 | |
| 		  { IREG reg; INT scale; ADDR off;}
 | |
| 			4 cost(5,5) off "(" reg "*" scale ")" .
 | |
| 
 | |
| label		= { ADDR off;} 4 off .
 | |
| 
 | |
| /*****************************************************************/
 | |
| SETS
 | |
| /*****************************************************************/
 | |
| 
 | |
| /* Mode refering to a word in memory */
 | |
| memory2		= EXTERN2 + indir_r2 + indir_r_off2 + LOCAL2 +
 | |
| 		  indir_indexed_r_off2 + indir_indexed_off2 .
 | |
| memory1		= EXTERN1 + indir_r1 + indir_r_off1 + LOCAL1 +
 | |
| 		  indir_indexed_r_off1 + indir_indexed_off1 .
 | |
| memory		= EXTERN + indir_r + indir_r_off + LOCAL +
 | |
| 		  indir_indexed_r_off + indir_indexed_off .
 | |
| noacc		= EXTERN + LOCAL + BXREG + CXREG + RREG .
 | |
| const		= ANYCON + ADDR_EXTERN + CONSTR .
 | |
| register	= REG + ADDREG + RREG + IREG .
 | |
| addreg		= ADDREG + RREG .
 | |
| anyreg		= register + AREG .
 | |
| rm		= anyreg + memory .
 | |
| rmorconst	= const + rm .
 | |
| regorconst	= const + anyreg .
 | |
| dest		= register + memory .
 | |
| 
 | |
| rm1		= REG1 + memory1 .
 | |
| rmorconst1	= const + rm1 .
 | |
| rm2		= REG2 + memory2 .
 | |
| rmorconst2	= const + rm2 .
 | |
| regorconst124	= REG1 + REG2 + GENREG + const .
 | |
| regorconst24	= REG2 + GENREG + const .
 | |
| dest1		= REG1 + memory1 .
 | |
| dest2		= REG2 + memory2 .
 | |
| 
 | |
| /* Modes used to indicate tokens to be removed from the fakestack */
 | |
| reg_indir	= indir_r1 + indir_r2 + indir_r_off1 + indir_r_off2 + indir_r +
 | |
| 		  indir_r_off .
 | |
| indexed		= indir_indexed_r_off1 + indir_indexed_r_off2 +
 | |
| 		  indir_indexed_r_off + indir_indexed_off1 +
 | |
| 		  indir_indexed_off2 + indir_indexed_off .
 | |
| indir		= reg_indir + indexed .
 | |
| externals	= EXTERN2 + EXTERN1 + EXTERN .
 | |
| locals		= LOCAL2 + LOCAL1 + LOCAL .
 | |
| mem_nonlocals	= externals + reg_indir .
 | |
| all_mems	= mem_nonlocals + locals .
 | |
| 
 | |
| /* Miscellaneous */
 | |
| reg_off		= Xreg_off + Rreg_off .
 | |
| halfindir	= reg_off + ADDR_LOCAL + indexed_r_off + indexed_off .
 | |
| some_off	= halfindir + ADDR_EXTERN + AREG .
 | |
| a_word		= rmorconst + halfindir .
 | |
| 
 | |
| /*****************************************************************/
 | |
| INSTRUCTIONS
 | |
| /*****************************************************************/
 | |
| 
 | |
| cost(2,2)
 | |
| adc rm:rw:cc, regorconst:ro.
 | |
| adc anyreg:rw:cc, rmorconst:ro.
 | |
| #ifdef REGVARS
 | |
| add LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
 | |
| #endif
 | |
| add anyreg:rw:cc, rmorconst:ro.
 | |
| add rm:rw:cc, regorconst:ro.
 | |
| #ifdef REGVARS
 | |
| axx "syntax error" LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
 | |
| #endif
 | |
| axx "syntax error" anyreg:rw:cc, rmorconst:ro.
 | |
| axx "syntax error" rm:rw:cc, regorconst:ro.
 | |
| #ifdef REGVARS
 | |
| and LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
 | |
| #endif
 | |
| and rm:rw:cc, regorconst:ro.
 | |
| and anyreg:rw:cc, rmorconst:ro.
 | |
| cdq kills edx cost(1,3).
 | |
| cmp rm:ro, regorconst:ro kills :cc.
 | |
| cmp anyreg:ro, rmorconst:ro kills :cc.
 | |
| cmpb rm1:rw, const:ro kills :cc.
 | |
| cmpw "o16 cmp" rm2:rw, const:ro kills :cc cost(3,2).
 | |
| dec anyreg:rw:cc cost(1,2).
 | |
| dec rm:rw:cc.
 | |
| div rm:ro kills:cc eax edx cost(2,43).
 | |
| idiv rm:ro kills:cc eax edx cost(2,43).
 | |
| imul rm:rw, anyreg:ro kills:cc cost(3,41).
 | |
| imul anyreg:rw, rm:ro kills:cc cost(3,41).
 | |
| imul anyreg:wo, rm:ro, const:ro kills :cc cost(2,38).
 | |
| inc anyreg:rw:cc cost(1,2).
 | |
| inc rm:rw:cc.
 | |
| ja label cost(1,4).
 | |
| jae label cost(1,4).
 | |
| jb label cost(1,4).
 | |
| jbe label cost(1,4).
 | |
| jcxz label cost(1,4).
 | |
| je label cost(1,4).
 | |
| jg label cost(1,4).
 | |
| jge label cost(1,4).
 | |
| jl label cost(1,4).
 | |
| jle label cost(1,4).
 | |
| jne label cost(1,4).
 | |
| jmp label cost(1,4).
 | |
| proccall "call" label+rm cost(1,8).
 | |
| jxx "syntax error" label cost(1,4).
 | |
| setxx "syntax error" REG1:rw cost(2,4).
 | |
| setle REG1:rw cost(2,4).
 | |
| setg REG1:rw cost(2,4).
 | |
| lea anyreg:rw, halfindir:ro.
 | |
| lea LOCAL:rw, halfindir:ro.	/* only for register variables, UNSAFE!!! */
 | |
| leave cost(1,4).
 | |
| loop label kills ecx.
 | |
| #ifdef REGVARS
 | |
| mov LOCAL:wo, rmorconst:ro.	/* only for register variables, UNSAFE!!! */
 | |
| #endif
 | |
| mov a_word:wo, regorconst:ro.
 | |
| mov anyreg:wo, rmorconst:ro.
 | |
| movb rm1:wo, regorconst124:ro.
 | |
| movb REG1:wo, rm1:ro.
 | |
| movw "o16 mov" rm2:wo, regorconst124:ro cost(3,2).
 | |
| movw "o16 mov" REG2:wo, rmorconst2:ro cost(3,2).
 | |
| movsxb anyreg:wo, REG+rm1:ro.
 | |
| movsx anyreg:wo, REG+rm2:ro.
 | |
| movzxb anyreg:wo, REG+rm1:ro.
 | |
| movzx anyreg:wo, REG+rm2:ro.
 | |
| mul rmorconst:ro kills :cc eax edx cost(2,41).
 | |
| neg rmorconst:rw:cc.
 | |
| not rmorconst:rw.
 | |
| #ifdef REGVARS
 | |
| or LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
 | |
| #endif
 | |
| or rm:rw:cc, regorconst:ro.
 | |
| or anyreg:rw:cc, rmorconst:ro.
 | |
| pop anyreg:wo cost(1,4).
 | |
| pop rm:wo.
 | |
| push anyreg:ro cost(1,2).
 | |
| push const:ro cost(1,2).
 | |
| push rm:ro cost(2,5).
 | |
| rcl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
 | |
| rcr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc cost(2,10).
 | |
| ret cost(1,10).
 | |
| rol rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| ror rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| sal rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| sar rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| sbb rm:rw:cc, regorconst:ro.
 | |
| sbb anyreg:rw:cc, rmorconst:ro.
 | |
| shl rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| shr rm:rw, ANYCON+SHIFT_CREG:ro kills :cc.
 | |
| #ifdef REGVARS
 | |
| sub LOCAL:rw:cc, rmorconst:ro.	/* only for register variables; UNSAFE !!! */
 | |
| #endif
 | |
| sub rm:rw:cc, regorconst:ro.
 | |
| sub anyreg:rw:cc, rmorconst+halfindir:ro.
 | |
| check "test" rm:ro, regorconst:ro kills :cc.
 | |
| check "test" anyreg:ro, rmorconst:ro kills :cc.
 | |
| testb "testb" rm1:ro, regorconst124:ro kills :cc.
 | |
| testb "testb" REG1:ro, rmorconst1:ro kills :cc.
 | |
| testw "o16 test" rm2:ro, regorconst24:ro kills :cc.
 | |
| testw "o16 test" REG2:ro, rmorconst2:ro kills :cc.
 | |
| testl "test" rm:ro, regorconst:ro kills :cc.
 | |
| testl "test" REG:ro, rmorconst:ro kills :cc.
 | |
| uxx "syntax error"  rm:rw:cc.
 | |
| xchg rm:rw, anyreg:rw.
 | |
| xchg anyreg:rw, rm:rw.
 | |
| xor rm:rw:cc, regorconst:ro.
 | |
| xor anyreg:rw:cc, rmorconst:ro.
 | |
| xorb rm1:rw:cc, regorconst124:ro.
 | |
| xorb anyreg:rw:cc, rmorconst1:ro.
 | |
| xorw "o16 xor" rm2:rw:cc, regorconst124:ro.
 | |
| xorw "o16 xor" anyreg:rw:cc, rmorconst2:ro.
 | |
| 
 | |
| killreg "! kill" anyreg:wo cost(0,0).
 | |
| killcc "! kill cc" kills:cc cost(0,0).
 | |
| 
 | |
| 
 | |
| /*****************************************************************/
 | |
| MOVES
 | |
| /*****************************************************************/
 | |
| 
 | |
| #ifdef REGVARS
 | |
| from rmorconst to LOCAL		/* unsafe !!! */
 | |
| gen mov %2,%1
 | |
| #endif
 | |
| 
 | |
| from rm to register
 | |
| gen mov %2,%1
 | |
| 
 | |
| from anyreg to dest
 | |
| gen mov %2,%1
 | |
| 
 | |
| from halfindir to register+AREG
 | |
| gen lea %2,%1
 | |
| 
 | |
| from halfindir to LOCAL		/* unsafe !!! */
 | |
| gen lea %2,%1
 | |
| 
 | |
| from rm1 to REG1
 | |
| gen movb %2,%1
 | |
| 
 | |
| from rm2 to REG2
 | |
| gen movw %2,%1
 | |
| 
 | |
| from GENREG to rm1
 | |
| gen movb %2,%1.1
 | |
| 
 | |
| from GENREG to rm2
 | |
| gen movw %2,%1
 | |
| 
 | |
| from REG2 to rm1
 | |
| gen movb %2,%1.1
 | |
| 
 | |
| from ANYCON %val==0 to register
 | |
| gen xor %2,%2
 | |
| 
 | |
| from ANYCON %val==0 to REG1
 | |
| gen xorb %2,%2
 | |
| 
 | |
| from ANYCON %val==0 to REG2
 | |
| gen xorw %2,%2
 | |
| 
 | |
| from const to dest
 | |
| gen mov %2,%1
 | |
| 
 | |
| from const+REG1 to rm1
 | |
| gen movb %2,%1
 | |
| 
 | |
| from const+REG2 to rm2
 | |
| gen movw %2,%1
 | |
| 
 | |
| /*****************************************************************/
 | |
| TESTS
 | |
| /*****************************************************************/
 | |
| 
 | |
| to test anyreg
 | |
| gen testl %1,%1
 | |
| 
 | |
| to test memory
 | |
| gen cmp %1, {ANYCON,0}
 | |
| 
 | |
| to test REG1
 | |
| gen testb %1,%1
 | |
| 
 | |
| to test memory1
 | |
| gen cmpb %1, {ANYCON,0}
 | |
| 
 | |
| to test REG2
 | |
| gen testw %1,%1
 | |
| 
 | |
| to test memory2
 | |
| gen cmpw %1, {ANYCON,0}
 | |
| 
 | |
| 
 | |
| /*****************************************************************/
 | |
| STACKINGRULES
 | |
| /*****************************************************************/
 | |
| 
 | |
| from rm to STACK
 | |
|   gen push %1
 | |
| 
 | |
| from const to STACK
 | |
|   gen push %1
 | |
| 
 | |
| from rm1 to STACK
 | |
|   uses REG
 | |
|   gen movzxb %a,%1
 | |
|       push %a
 | |
| 
 | |
| from rm1 to STACK
 | |
|   gen push eax
 | |
|       movzxb eax,%1
 | |
|       xchg {indir_r,esp},eax
 | |
| 
 | |
| from rm2 to STACK
 | |
|   uses REG
 | |
|   gen movzx %a,%1
 | |
|       push %a
 | |
| 
 | |
| from rm2 to STACK
 | |
|   gen push eax
 | |
|       movzx eax,%1
 | |
|       xchg {indir_r,esp},eax
 | |
| 
 | |
| from Xreg_off to STACK
 | |
|   gen add %1.reg,{CONSTR,%1.off}
 | |
|       push %1.reg
 | |
| 
 | |
| from ADDR_LOCAL %ind==0 to STACK
 | |
|   gen push ebp
 | |
| 
 | |
| from halfindir to STACK
 | |
|   uses REG
 | |
|   gen move %1,%a
 | |
|       push %a
 | |
| 
 | |
| from halfindir to STACK
 | |
|   gen push eax
 | |
|       lea eax,%1
 | |
|       xchg {indir_r,esp},eax
 | |
| 
 | |
| 
 | |
| /*****************************************************************/
 | |
| COERCIONS
 | |
| /*****************************************************************/
 | |
| 
 | |
| /***************************
 | |
|  * From source to register *
 | |
|  ***************************/
 | |
| 
 | |
| from rmorconst
 | |
|   uses reusing %1,REG=%1		yields %a
 | |
| from rmorconst
 | |
|   uses reusing %1,IREG=%1		yields %a
 | |
| 
 | |
| from Xreg_off
 | |
|   gen add %1.reg,{CONSTR,%1.off}	yields %1.reg
 | |
| 
 | |
| from halfindir
 | |
|   uses reusing %1,ADDREG
 | |
|   gen move %1,%a			yields %a
 | |
| 
 | |
| from halfindir
 | |
|   uses reusing %1,REG
 | |
|   gen move %1,%a			yields %a
 | |
| 
 | |
| from halfindir
 | |
|   uses reusing %1,IREG
 | |
|   gen move %1,%a			yields %a
 | |
| 
 | |
| /************************
 | |
|  * From source to token *
 | |
|  ************************/
 | |
| 
 | |
| from ANYCON				yields {ADDR_EXTERN,%1.val}
 | |
| 
 | |
| /****************
 | |
|  * From source1 *
 | |
|  ****************/
 | |
| 
 | |
| from rm1
 | |
|   uses reusing %1,REG1=%1		yields %a
 | |
| 
 | |
| from rm1
 | |
|   uses GENREG
 | |
|   gen
 | |
|       movzxb %a,%1			yields %a
 | |
| 
 | |
| /****************
 | |
|  * From source2 *
 | |
|  ****************/
 | |
| 
 | |
| from rm2
 | |
|   uses reusing %1,REG2=%1		yields %a
 | |
| 
 | |
| from rm2
 | |
|   uses GENREG
 | |
|   gen
 | |
|       movzx %a,%1			yields %a
 | |
| 
 | |
| /************************
 | |
|  * From STACK coercions *
 | |
|  ************************/
 | |
| 
 | |
| from STACK
 | |
|   uses REG
 | |
|   gen pop %a				yields %a
 | |
| 
 | |
| 
 | |
| /*****************************************************************/
 | |
| PATTERNS
 | |
| /*****************************************************************/
 | |
| 
 | |
| /******************************************************************
 | |
|  *  Group 1 : Load Instructions					  *
 | |
|  ******************************************************************/
 | |
| 
 | |
| pat loc					yields {ANYCON,$1}
 | |
| 
 | |
| pat ldc					leaving loc 18 trp
 | |
| 
 | |
| pat lol					yields {LOCAL,$1,4}
 | |
| 
 | |
| pat stl lol $1==$2
 | |
| #ifdef REGVARS
 | |
| 	&& inreg($1) <= 0
 | |
| #endif
 | |
| 						leaving dup 4 stl $1
 | |
| 
 | |
| pat sdl ldl $1==$2				leaving dup 8 sdl $1
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lol dup stl $2==4 && inreg($1) <= 0 && inreg($3) > 0
 | |
| kills regvar($3)
 | |
| gen	move {LOCAL,$1,4}, {LOCAL,$3,4}
 | |
| 					yields {LOCAL,$3,4}
 | |
| #endif
 | |
| 
 | |
| pat loe					yields {EXTERN,$1}
 | |
| 
 | |
| pat ste loe $1==$2				leaving dup 4 ste $1
 | |
| 
 | |
| pat sde lde $1==$2				leaving dup 8 sde $1
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat loe dup stl $2==4 && inreg($3) > 0
 | |
| kills regvar($3)
 | |
| gen	move {EXTERN,$1}, {LOCAL,$3,4}
 | |
| 					yields {LOCAL,$3,4}
 | |
| #endif
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lil inreg($1) > 0			yields {indir_r, regvar($1)}
 | |
| #endif
 | |
| pat lil
 | |
|   uses ADDREG={indir_r_off,ebp,$1}	yields {indir_r,%a}
 | |
| 
 | |
| pat lil dup stl $2==4				leaving lil $1 stl $3 lol $3
 | |
| 
 | |
| pat sil lil $1==$2				leaving dup 4 sil $1
 | |
| 
 | |
| pat lof
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off,%1.reg,%1.reg2,
 | |
| 						%1.scale,%1.off+$1}
 | |
|   with exact indexed_off	yields {indir_indexed_off,%1.reg,
 | |
| 						%1.scale,%1.off+$1}
 | |
|   with exact reg_off		yields {indir_r_off,%1.reg,%1.off+$1}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN,%1.off+$1}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL,%1.ind + $1,4}
 | |
|   with addreg			yields {indir_r_off,%1,$1}
 | |
| 
 | |
| pat lal					yields {ADDR_LOCAL,$1}
 | |
| 
 | |
| pat lae					yields {ADDR_EXTERN,$1}
 | |
| 
 | |
| pat lpb						leaving adp SL
 | |
| 
 | |
| pat lxl $1==0				yields {ADDR_LOCAL,0}
 | |
| 
 | |
| pat lxl $1==1				yields {LOCAL,SL,4}
 | |
| 
 | |
| pat lxl $1==2
 | |
|   uses ADDREG={indir_r_off,ebp,SSL}	yields {indir_r_off,%a,SSL}
 | |
| 
 | |
| pat lxl $1>2
 | |
|   uses ADDREG={indir_r_off,ebp,SSL},
 | |
|        CXREG={ANYCON,$1-1}
 | |
|   gen 1:
 | |
|       mov %a,{indir_r_off,%a,SSL}
 | |
|       loop {label,1b}			yields %a
 | |
| 
 | |
| pat lxa $1==0				yields {ADDR_LOCAL,SL}
 | |
| 
 | |
| pat lxa $1==1
 | |
|   uses ADDREG={indir_r_off,ebp,SSL}	yields {Xreg_off,%a,SSL}
 | |
| 
 | |
| pat lxa $1==2
 | |
|   uses ADDREG={indir_r_off,ebp,SSL}
 | |
|   gen move {indir_r_off,%a,SSL},%a	yields {Xreg_off,%a,SSL}
 | |
| 
 | |
| pat lxa $1>2
 | |
|   uses ADDREG={indir_r_off,ebp,SSL},
 | |
|        CXREG={ANYCON,$1-1}
 | |
|   gen 1:
 | |
|       mov %a,{indir_r_off,%a,SSL}
 | |
|       loop {label,1b}			yields {Xreg_off,%a,SSL}
 | |
| 
 | |
| pat dch						leaving loi 4
 | |
| 
 | |
| pat loi $1==2
 | |
|   with addreg			yields {indir_r2,%1}
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off2, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact indexed_off	yields {indir_indexed_off2, %1.reg,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact reg_off		yields {indir_r_off2,%1.reg,%1.off}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN2,%1.off}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL2,%1.ind,2}
 | |
| 
 | |
| pat loi $1==1
 | |
|   with addreg			yields {indir_r1,%1}
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off1, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact indexed_off	yields {indir_indexed_off1, %1.reg,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact reg_off		yields {indir_r_off1,%1.reg,%1.off}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN1,%1.off}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL1,%1.ind,1}
 | |
| 
 | |
| pat loi $1==4
 | |
|   with addreg			yields {indir_r,%1}
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact indexed_off	yields {indir_indexed_off, %1.reg,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact reg_off		yields {indir_r_off,%1.reg,%1.off}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN,%1.off}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL,%1.ind,4}
 | |
| 
 | |
| pat loi $1==8
 | |
|   with addreg			yields {indir_r_off,%1,4}
 | |
| 				       {indir_r,%1}
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off+4}
 | |
| 					{indir_indexed_r_off, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact indexed_off	yields {indir_indexed_off, %1.reg,
 | |
| 						%1.scale, %1.off+4}
 | |
| 					{indir_indexed_off, %1.reg,
 | |
| 						%1.scale, %1.off}
 | |
|   with exact reg_off		yields {indir_r_off,%1.reg,%1.off+4}
 | |
| 				       {indir_r_off,%1.reg,%1.off}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL,%1.ind+4,4}
 | |
| 				       {LOCAL,%1.ind,4}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN,%1.off + 4}
 | |
| 				       {EXTERN,%1.off}
 | |
| pat loi
 | |
|   with BXREG
 | |
|   kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label,".loi"}
 | |
| 
 | |
| pat los $1==4
 | |
|   with CXREG BXREG
 | |
|   kills ALL
 | |
|   gen proccall {label,".los"}
 | |
| 
 | |
| pat ldl					yields {LOCAL,$1+4,4}
 | |
| 					       {LOCAL,$1,4}
 | |
| 
 | |
| pat lde					yields {EXTERN,$1+4}
 | |
| 					       {EXTERN,$1}
 | |
| 
 | |
| pat ldf
 | |
|   with exact reg_off			yields {indir_r_off,%1.reg,
 | |
| 						%1.off + 4 + $1}
 | |
| 					       {indir_r_off,%1.reg,
 | |
| 						%1.off + $1}
 | |
|   with exact indexed_r_off	yields {indir_indexed_r_off, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off+$1+4}
 | |
| 					{indir_indexed_r_off, %1.reg, %1.reg2,
 | |
| 						%1.scale, %1.off+$1}
 | |
|   with exact indexed_off	yields {indir_indexed_off, %1.reg,
 | |
| 						%1.scale, %1.off+$1+4}
 | |
| 					{indir_indexed_off, %1.reg,
 | |
| 						%1.scale, %1.off+$1}
 | |
|   with addreg				yields {indir_r_off,%1,$1+4}
 | |
| 					       {indir_r_off,%1,$1}
 | |
|   with exact ADDR_EXTERN	yields {EXTERN,%1.off+4+$1}
 | |
| 				       {EXTERN,%1.off+$1}
 | |
|   with exact ADDR_LOCAL		yields {LOCAL,%1.ind + $1 + 4,4}
 | |
| 				       {LOCAL,%1.ind + $1,4}
 | |
| 
 | |
| pat lpi				yields {ADDR_EXTERN,$1}
 | |
| 
 | |
| /* this code sequence is generated by the C-compiler to tackle
 | |
|    char parameters, on the 80386 it reduces to nil */
 | |
| 
 | |
| pat lol lal sti $1==$2 && $3<=4
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 2 : Store Instructions				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat stl inreg($1)==reg_any
 | |
|   with rmorconst
 | |
|   kills regvar($1)
 | |
|   gen move %1, {LOCAL,$1,4}
 | |
|   with exact halfindir
 | |
|   kills regvar($1)
 | |
|   gen move %1, {LOCAL,$1,4}
 | |
|   with exact STACK
 | |
|   kills regvar($1)
 | |
|   gen pop {LOCAL, $1, 4}
 | |
| #endif
 | |
| pat stl
 | |
|   with regorconst
 | |
|   kills indir,locals %ind+%size > $1 && %ind < $1+4
 | |
|   gen move %1,{LOCAL,$1,4}
 | |
|   with exact STACK
 | |
|   kills ALL
 | |
|   gen pop {indir_r_off,ebp,$1}
 | |
| 
 | |
| pat ste
 | |
|   with regorconst
 | |
|   kills mem_nonlocals
 | |
|   gen move %1,{EXTERN,$1}
 | |
|   with exact STACK
 | |
|   kills ALL
 | |
|   gen pop {EXTERN,$1}
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat sil inreg($1)==reg_any
 | |
|   with regorconst
 | |
|   kills all_mems
 | |
|   gen move %1,{indir_r,regvar($1)}
 | |
|   with exact STACK
 | |
|   kills ALL
 | |
|   gen pop {indir_r,regvar($1)}
 | |
| #endif
 | |
| pat sil
 | |
|   with regorconst
 | |
|   kills all_mems
 | |
|   uses ADDREG={indir_r_off,ebp,$1}
 | |
|   gen move %1,{indir_r,%a}
 | |
|       killreg %a
 | |
|   with exact STACK
 | |
|   kills ALL
 | |
|   uses ADDREG={indir_r_off,ebp,$1}
 | |
|   gen pop {indir_r,%a}
 | |
|       killreg %a
 | |
| 
 | |
| pat stf
 | |
|   with addreg regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off,%1,$1}
 | |
|   with exact addreg STACK
 | |
|   kills ALL
 | |
|   gen pop {indir_r_off, %1,$1}
 | |
|   with reg_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off,%1.reg,%1.off+$1}
 | |
|   with exact reg_off STACK
 | |
|   gen pop {indir_r_off,%1.reg,$1+%1.off}
 | |
|   with indexed_r_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
|   with exact indexed_r_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
|   with indexed_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
|   with exact indexed_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
|   with ADDR_LOCAL regorconst
 | |
|   kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
 | |
|   gen move %2,{LOCAL,%1.ind+$1,4}
 | |
|   with exact ADDR_LOCAL STACK
 | |
|   kills indir,locals %ind+%size > %1.ind+$1 && %ind < %1.ind+$1+4
 | |
|   gen pop {LOCAL,%1.ind+$1,4}
 | |
|   with ADDR_EXTERN regorconst
 | |
|   kills mem_nonlocals
 | |
|   gen move %2,{EXTERN,%1.off+$1}
 | |
|   with exact ADDR_EXTERN STACK
 | |
|   kills mem_nonlocals
 | |
|   gen pop {EXTERN,%1.off+$1}
 | |
| 
 | |
| pat sti $1==4
 | |
|   with addreg regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r,%1}
 | |
|   with exact addreg STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_r,%1}
 | |
|   with reg_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off,%1.reg,%1.off}
 | |
|   with exact reg_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_r_off,%1.reg,%1.off}
 | |
|   with indexed_r_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
 | |
|   with exact indexed_r_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off}
 | |
|   with indexed_off regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off}
 | |
|   with exact indexed_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off}
 | |
|   with ADDR_LOCAL regorconst
 | |
|   kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
 | |
|   gen move %2,{LOCAL,%1.ind,4}
 | |
|   with exact ADDR_LOCAL STACK
 | |
|   kills indir,locals %ind+%size > %1.ind && %ind < %1.ind+4
 | |
|   gen pop {LOCAL,%1.ind,4}
 | |
|   with ADDR_EXTERN regorconst
 | |
|   kills mem_nonlocals
 | |
|   gen move %2,{EXTERN,%1.off}
 | |
|   with exact ADDR_EXTERN STACK
 | |
|   kills mem_nonlocals
 | |
|   gen pop {EXTERN,%1.off}
 | |
| 
 | |
| pat sti $1==1
 | |
|   with addreg regorconst124
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r1,%1}
 | |
|   with reg_off regorconst124
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off1,%1.reg,%1.off}
 | |
|   with indexed_r_off regorconst124
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_r_off1,%1.reg,%1.reg2,%1.scale,%1.off}
 | |
|   with indexed_off regorconst124
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_off1,%1.reg,%1.scale,%1.off}
 | |
|   with ADDR_EXTERN regorconst124
 | |
|   kills mem_nonlocals
 | |
|   gen move %2,{EXTERN1,%1.off}
 | |
|   with ADDR_LOCAL regorconst124
 | |
|   kills indir,locals %ind<%1.ind+1 && %ind+%size>%1.ind
 | |
|   gen move %2,{indir_r_off1,ebp,%1.ind}
 | |
| 
 | |
| pat sti $1==2
 | |
|   with addreg regorconst24
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r2,%1}
 | |
|   with reg_off regorconst24
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off2,%1.reg,%1.off}
 | |
|   with indexed_r_off regorconst24
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_r_off2,%1.reg,%1.reg2,%1.scale,%1.off}
 | |
|   with indexed_off regorconst24
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_off2,%1.reg,%1.scale,%1.off}
 | |
|   with ADDR_EXTERN regorconst24
 | |
|   kills mem_nonlocals
 | |
|   gen move %2,{EXTERN2,%1.off}
 | |
|   with ADDR_LOCAL regorconst24
 | |
|   kills indir,locals %ind<%1.ind+2 && %ind+%size>%1.ind
 | |
|   gen move %2,{indir_r_off2,ebp,%1.ind}
 | |
| 
 | |
| pat sti $1==8			leaving sdf 0
 | |
| 
 | |
| pat sti
 | |
|   with BXREG
 | |
|   kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".sti"}
 | |
| 
 | |
| /* this sort of construction gives problems in the codegenerator
 | |
|    because of the potential very large lookahead
 | |
| 
 | |
|   with addreg
 | |
|   kills ALL
 | |
|   gen pop (%1)
 | |
|       add %1,{ANYCON,2}			yields %1	leaving sti $1-4
 | |
| 
 | |
| */
 | |
| 
 | |
| pat sts $1==4
 | |
|   with CXREG BXREG
 | |
|   kills ALL
 | |
|   gen proccall {label,".sts"}
 | |
| 
 | |
| pat sdl
 | |
|   with regorconst regorconst	yields %2 %1
 | |
| 					leaving stl $1 stl $1+4
 | |
|   with exact STACK			leaving stl $1 stl $1+4
 | |
| 
 | |
| pat sde
 | |
|   with regorconst regorconst	yields %2 %1
 | |
| 					leaving ste $1 ste $1+4
 | |
|   with exact STACK			leaving ste $1 ste $1+4
 | |
| 
 | |
| pat sdf
 | |
|   with addreg regorconst regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off,%1,$1}
 | |
|       move %3,{indir_r_off,%1,$1+4}
 | |
|   with exact addreg STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_r_off,%1,$1}
 | |
|       pop {indir_r_off,%1,$1+4}
 | |
|   with reg_off regorconst regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_r_off,%1.reg,%1.off+$1}
 | |
|       move %3,{indir_r_off,%1.reg,%1.off+$1+4}
 | |
|   with exact reg_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_r_off,%1.reg,$1+%1.off}
 | |
|       pop {indir_r_off,%1.reg,$1+%1.off+4}
 | |
|   with indexed_r_off regorconst regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
|       move %3,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
 | |
|   with exact indexed_r_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
|       pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4+$1}
 | |
|   with indexed_off regorconst regorconst
 | |
|   kills all_mems
 | |
|   gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
|       move %3,{indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
 | |
|   with exact indexed_off STACK
 | |
|   kills all_mems
 | |
|   gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
|       pop {indir_indexed_off,%1.reg,%1.scale,%1.off+4+$1}
 | |
|   with ADDR_LOCAL regorconst regorconst
 | |
|   kills indir,locals %ind+%size > $1 && %ind < $1+8
 | |
|   gen	move %2,{LOCAL,%1.ind+$1,4}
 | |
| 	move %3,{LOCAL,%1.ind+$1+4,4}
 | |
|   with exact ADDR_LOCAL STACK
 | |
|   kills indir,locals %ind+%size > $1 && %ind < $1+8
 | |
|   gen	pop {LOCAL,%1.ind+$1,4}
 | |
| 	pop {LOCAL,%1.ind+$1+4,4}
 | |
|   with ADDR_EXTERN regorconst regorconst
 | |
|   kills mem_nonlocals
 | |
|   gen	move %2,{EXTERN,%1.off+$1}
 | |
| 	move %3,{EXTERN,%1.off+$1+4}
 | |
|   with exact ADDR_EXTERN STACK
 | |
|   kills mem_nonlocals
 | |
|   gen	pop {EXTERN,%1.off+$1}
 | |
| 	pop {EXTERN,%1.off+$1+4}
 | |
| 
 | |
| 
 | |
| /****************************************************************
 | |
|  *  Group 3 : Integer Arithmetic.				*
 | |
|  *								*
 | |
|  *  Implemented (sometimes with the use of subroutines) :	*
 | |
|  *  4 byte arithmetic.						*
 | |
|  ****************************************************************/
 | |
| 
 | |
| pat adi $1==4
 | |
| #ifdef REGVARS
 | |
| with exact ANYCON RREG
 | |
| 				yields {Rreg_off,%2,%1.val}
 | |
| with exact RREG ANYCON
 | |
| 				yields {Rreg_off,%1,%2.val}
 | |
| #endif
 | |
| with REG rmorconst
 | |
|   gen add %1,%2			yields %1
 | |
| with rmorconst REG
 | |
|   gen add %2,%1			yields %2
 | |
| with EXACT rmorconst const
 | |
|   uses reusing %1,REG=%1
 | |
|   gen add %a,%2			yields %a
 | |
| 
 | |
| /*
 | |
| pat adi !defined($1)
 | |
| with CXREG ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".adi"}	yields eax
 | |
| */
 | |
| 
 | |
| pat sbi $1==4
 | |
| 
 | |
| with rmorconst REG
 | |
|   gen sub %2,%1			yields %2
 | |
| with EXACT REG rmorconst
 | |
|   gen sub %1,%2
 | |
|       neg %1			yields %1
 | |
| 
 | |
| /*
 | |
| pat sbi !defined($1)
 | |
| with CXREG ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".sbi"}	yields eax
 | |
| */
 | |
| 
 | |
| pat mli $1==4
 | |
| with rm REG
 | |
|   gen imul %2,%1		yields %2
 | |
| with REG rm
 | |
|   gen imul %1,%2		yields %1
 | |
| with const rm
 | |
|   uses reusing %2,REG
 | |
|   gen imul %a,%2,%1		yields %a
 | |
| with rm const
 | |
|   uses reusing %1,REG
 | |
|   gen imul %a,%1,%2		yields %a
 | |
| 
 | |
| /*
 | |
| pat mli !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".mli"}
 | |
| */
 | |
| 
 | |
| pat dvi $1==4
 | |
| with noacc ACC
 | |
|   uses DXREG
 | |
|   gen cdq.
 | |
|       idiv %1			yields eax
 | |
| 
 | |
| /*
 | |
| pat dvi !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".dvi"}
 | |
| */
 | |
| 
 | |
| pat rmi $1==4
 | |
| with noacc ACC
 | |
|   uses DXREG
 | |
|   gen cdq.
 | |
|       idiv %1			yields edx
 | |
| 
 | |
| /*
 | |
| pat rmi !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".rmi"}
 | |
| */
 | |
| 
 | |
| pat ngi $1==4
 | |
| with REG
 | |
|   gen neg %1			yields %1
 | |
| 
 | |
| /*
 | |
| pat ngi !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".ngi"}
 | |
| */
 | |
| 
 | |
| pat sli $1==4
 | |
| with ANYCON REG
 | |
|   gen sal %2,%1			yields %2
 | |
| with SHIFT_CREG REG
 | |
|   gen sal %2,cl			yields %2
 | |
| 
 | |
| /*
 | |
| pat sli !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".sli"}
 | |
| */
 | |
| 
 | |
| pat sri $1==4
 | |
| with SHIFT_CREG REG
 | |
|   gen sar %2,cl			yields %2
 | |
| with ANYCON REG
 | |
|   gen sar %2,%1			yields %2
 | |
| 
 | |
| /*
 | |
| pat sri !defined($1)
 | |
| with ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".sri"}
 | |
| */
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 4: Unsigned Arithmetic				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat adu					leaving adi $1
 | |
| pat loc lol adu stl $1==1 && $3==4 && $2==$4	leaving inl $2
 | |
| pat loc loe adu ste $1==1 && $3==4 && $2==$4	leaving ine $2
 | |
| pat loc lol adu $1==1 && $3==4		leaving lol $2 inc
 | |
| pat loc loe adu $1==1 && $3==4		leaving loe $2 inc
 | |
| pat loc lil adu $1==1 && $3==4		leaving lil $2 inc
 | |
| pat loc lol adu stl $1==0-1 && $3==4 && $2==$4	leaving del $2
 | |
| pat loc loe adu ste $1==0-1 && $3==4 && $2==$4	leaving dee $2
 | |
| pat loc lol adu $1==0-1 && $3==4		leaving lol $2 dec
 | |
| pat loc loe adu $1==0-1 && $3==4		leaving loe $2 dec
 | |
| pat loc lil adu $1==0-1 && $3==4		leaving lil $2 dec
 | |
| pat sbu					leaving sbi $1
 | |
| pat lol loc sbu stl $1==$4 && $2==1 && $3==4	leaving del $1
 | |
| pat loe loc sbu ste $1==$4 && $2==1 && $3==4	leaving dee $1
 | |
| pat lol loc sbu $2==1 && $3==4		leaving lol $1 dec
 | |
| pat loe loc sbu $2==1 && $3==4		leaving loe $1 dec
 | |
| pat lil loc sbu $2==1 && $3==4		leaving lil $1 dec
 | |
| pat lol loc sbu stl $1==$4 && $2==0-1 && $3==4	leaving inl $1
 | |
| pat loe loc sbu ste $1==$4 && $2==0-1 && $3==4	leaving ine $1
 | |
| pat lol loc sbu $2==0-1 && $3==4		leaving lol $1 inc
 | |
| pat loe loc sbu $2==0-1 && $3==4		leaving loe $1 inc
 | |
| pat lil loc sbu $2==0-1 && $3==4		leaving lil $1 inc
 | |
| pat mlu					leaving mli $1
 | |
| 
 | |
| pat loe loc loe adu ste $1==$3 && $1==$5 && $4==4
 | |
| uses REG = {EXTERN, $1}
 | |
|                                 yields %a leaving loc $2 loe $3 adu 4 ste $3
 | |
| 
 | |
| pat lol loc lol adu stl $1==$3 && $1==$5 && $4==4
 | |
| uses REG = {LOCAL, $1, 4}
 | |
|                                 yields %a leaving loc $2 lol $3 adu 4 stl $3
 | |
| 
 | |
| pat loe loc loe adi ste $1==$3 && $1==$5 && $4==4
 | |
| uses REG = {EXTERN, $1}
 | |
|                                 yields %a leaving loc $2 loe $3 adi 4 ste $3
 | |
| 
 | |
| pat lol loc lol adi stl $1==$3 && $1==$5 && $4==4
 | |
| uses REG = {LOCAL, $1, 4}
 | |
|                                 yields %a leaving loc $2 lol $3 adi 4 stl $3
 | |
| 
 | |
| pat dvu $1==4
 | |
| with noacc ACC
 | |
| uses DXREG={ANYCON,0}
 | |
| gen div %1			yields eax
 | |
| 
 | |
| /*
 | |
| pat dvu !defined($1)
 | |
| with ACC STACK
 | |
| kills ALL
 | |
| gen proccall {label,".dvu"}
 | |
| */
 | |
| 
 | |
| pat rmu $1==4
 | |
| with noacc ACC
 | |
| uses DXREG={ANYCON,0}
 | |
| gen div %1			yields edx
 | |
| 
 | |
| /*
 | |
| pat rmu !defined($1)
 | |
| with ACC STACK
 | |
| kills ALL
 | |
| gen proccall {label,".rmu"}
 | |
| */
 | |
| 
 | |
| pat slu					leaving sli $1
 | |
| pat loc slu					leaving loc $1 sli $2
 | |
| 
 | |
| pat sru $1==4
 | |
| with SHIFT_CREG REG
 | |
| gen shr %2,cl			yields %2
 | |
| with ANYCON REG
 | |
| gen shr %2,%1			yields %2
 | |
| 
 | |
| /*
 | |
| pat sru !defined($1)
 | |
| with ACC STACK
 | |
| kills ALL
 | |
| gen proccall {label,".sru"}
 | |
| */
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 5: Floating Point Instructions			   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat adf $1==4		leaving cal ".adf4" asp 4
 | |
| pat adf $1==8		leaving cal ".adf8" asp 8
 | |
| pat sbf $1==4		leaving cal ".sbf4" asp 4
 | |
| pat sbf $1==8		leaving cal ".sbf8" asp 8
 | |
| pat mlf $1==4		leaving cal ".mlf4" asp 4
 | |
| pat mlf $1==8		leaving cal ".mlf8" asp 8
 | |
| pat dvf $1==4		leaving cal ".dvf4" asp 4
 | |
| pat dvf $1==8		leaving cal ".dvf8" asp 8
 | |
| pat ngf $1==4		leaving cal ".ngf4"
 | |
| pat ngf $1==8		leaving cal ".ngf8"
 | |
| pat fif $1==4		leaving lor 1 cal ".fif4" asp 4
 | |
| pat fif $1==8		leaving lor 1 cal ".fif8" asp 4
 | |
| pat fef $1==4		leaving lor 1 adp 0-4 cal ".fef4"
 | |
| pat fef $1==8		leaving lor 1 adp 0-4 cal ".fef8"
 | |
| 
 | |
| /******************************************************************
 | |
|  *  Group 6: Pointer Arithmetic					  *
 | |
|  ******************************************************************/
 | |
| 
 | |
| pat adp $1==1
 | |
| with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
 | |
| with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
 | |
| with exact indexed_r_off
 | |
| 			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
| with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
| with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
 | |
| with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
 | |
| with REG
 | |
|   gen inc %1		yields %1
 | |
| with ADDREG
 | |
|   gen killreg %1
 | |
| 			yields {Xreg_off, %1, $1}
 | |
| with exact RREG		yields {Rreg_off, %1, $1}
 | |
| 
 | |
| pat adp $1==0-1
 | |
| with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
 | |
| with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
 | |
| with exact indexed_r_off
 | |
| 			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
| with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
| with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
 | |
| with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
 | |
| with REG
 | |
|   gen dec %1		yields %1
 | |
| with ADDREG
 | |
|   gen killreg %1
 | |
| 			yields {Xreg_off, %1, $1}
 | |
| with exact RREG		yields {Rreg_off, %1, $1}
 | |
| 
 | |
| pat adp
 | |
| with exact Xreg_off	yields {Xreg_off,%1.reg,%1.off+$1}
 | |
| with exact Rreg_off	yields {Rreg_off,%1.reg,%1.off+$1}
 | |
| with exact indexed_r_off
 | |
| 			yields {indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+$1}
 | |
| with exact indexed_off	yields {indexed_off,%1.reg,%1.scale,%1.off+$1}
 | |
| with exact ADDR_EXTERN	yields {ADDR_EXTERN,%1.off+$1}
 | |
| with exact ADDR_LOCAL	yields {ADDR_LOCAL,%1.ind+$1}
 | |
| with ADDREG
 | |
|   gen killreg %1
 | |
| 			yields {Xreg_off,%1,$1}
 | |
| with exact RREG		yields {Rreg_off, %1, $1}
 | |
| with REG
 | |
|   gen add %1,{ANYCON,$1}	yields %1
 | |
| 
 | |
| pat ads stl $1==4			leaving adi 4 stl $2
 | |
| pat ads ste $1==4			leaving adi 4 ste $2
 | |
| pat ads sil $1==4			leaving adi 4 sil $2
 | |
| pat ads lol stf $1==4			leaving adi 4 lol $2 stf $3
 | |
| pat ads loe stf $1==4			leaving adi 4 loe $2 stf $3
 | |
| 
 | |
| pat ads $1==4
 | |
| with exact ANYCON Rreg_off
 | |
| 			yields {Rreg_off,%2.reg,%2.off+%1.val}
 | |
| with exact ANYCON Xreg_off
 | |
| 			yields {Xreg_off,%2.reg,%2.off+%1.val}
 | |
| with exact ANYCON indexed_r_off
 | |
| 			yields {indexed_r_off,%2.reg,%2.reg2,
 | |
| 					%2.scale,%2.off+%1.val}
 | |
| with exact ANYCON indexed_off
 | |
| 			yields {indexed_off,%2.reg,%2.scale,%2.off+%1.val}
 | |
| with exact ADDR_EXTERN Rreg_off
 | |
| 			yields {Rreg_off,%2.reg,%2.off+%1.off}
 | |
| with exact ADDR_EXTERN Xreg_off
 | |
| 			yields {Xreg_off,%2.reg,%2.off+%1.off}
 | |
| with exact ADDR_EXTERN indexed_r_off
 | |
| 			yields {indexed_r_off,%2.reg,%2.reg2,
 | |
| 					%2.scale,%2.off+%1.off}
 | |
| with exact ADDR_EXTERN indexed_off
 | |
| 			yields {indexed_off,%2.reg,%2.scale,%2.off+%1.off}
 | |
| with exact IREG reg_off
 | |
| 			yields {indexed_r_off,%2.reg,%1,1,%2.off}
 | |
| with exact reg_off IREG
 | |
| 			yields {indexed_r_off,%1.reg,%2,1,%1.off}
 | |
| with exact IREG ADDR_LOCAL
 | |
| 			yields {indexed_r_off,ebp,%1,1,%2.ind}
 | |
| with exact ADDR_LOCAL IREG
 | |
| 			yields {indexed_r_off,ebp,%2,1,%1.ind}
 | |
| with rmorconst Xreg_off
 | |
|   gen add %2.reg,%1	yields %2
 | |
| with Xreg_off rmorconst
 | |
|   gen add %1.reg,%2	yields %1
 | |
| with exact Xreg_off ANYCON
 | |
| 			yields {Xreg_off,%1.reg,%1.off+%2.val}
 | |
| with exact Rreg_off ANYCON
 | |
| 			yields {Rreg_off,%1.reg,%1.off+%2.val}
 | |
| with exact indexed_r_off ANYCON
 | |
| 			yields {indexed_r_off,%1.reg,%1.reg2,
 | |
| 					%1.scale,%1.off+%2.val}
 | |
| with exact indexed_off ANYCON
 | |
| 			yields {indexed_off,%1.reg,%1.scale,%1.off+%2.val}
 | |
| with exact Xreg_off ADDR_EXTERN
 | |
| 			yields {Xreg_off,%1.reg,%1.off+%2.off}
 | |
| with exact Rreg_off ADDR_EXTERN
 | |
| 			yields {Rreg_off,%1.reg,%1.off+%2.off}
 | |
| with exact indexed_r_off ADDR_EXTERN
 | |
| 			yields {indexed_r_off,%1.reg,%1.reg2,
 | |
| 					%1.scale,%1.off+%2.off}
 | |
| with exact indexed_off ADDR_EXTERN
 | |
| 			yields {indexed_off,%1.reg,%1.scale,%1.off+%2.off}
 | |
| with exact Xreg_off reg_off
 | |
|   gen add %1.reg,%2.reg
 | |
| 			yields {Xreg_off,%1.reg,%1.off+%2.off}
 | |
| with exact RREG ADDR_EXTERN
 | |
| 			yields {Rreg_off, %1, %2.off}
 | |
| with exact ADDR_EXTERN RREG
 | |
| 			yields {Rreg_off,%2,%1.off}
 | |
| 
 | |
| with exact rmorconst ADDR_EXTERN
 | |
|   uses reusing %1,ADDREG=%1
 | |
| 			yields {Xreg_off,%a,%2.off}
 | |
| with exact ADDR_EXTERN rmorconst
 | |
|   uses reusing %2,ADDREG=%2
 | |
| 			yields {Xreg_off,%a,%1.off}
 | |
| with rmorconst ADDREG
 | |
|   gen add %2,%1		yields %2
 | |
| with ADDREG rmorconst
 | |
|   gen add %1,%2		yields %1
 | |
| 
 | |
| pat sbs $1==4
 | |
| with exact ANYCON Xreg_off
 | |
| 			yields {Xreg_off,%2.reg,%2.off+"-"+%1.val}
 | |
| with exact ANYCON Rreg_off
 | |
| 			yields {Rreg_off,%2.reg,%2.off+"-"+%1.val}
 | |
| with exact ANYCON indexed_r_off
 | |
| 			yields {indexed_r_off,%2.reg,%2.reg2,%2.scale,
 | |
| 					%2.off+"-"+%1.val}
 | |
| with exact ANYCON indexed_off
 | |
| 			yields {indexed_off,%2.reg,%2.scale,%2.off+"-"+%1.val}
 | |
| with exact ANYCON ADDR_LOCAL
 | |
| 			yields {ADDR_LOCAL,%2.ind-%1.val}
 | |
| with rm Xreg_off
 | |
|   gen sub %2.reg,%1	yields {Xreg_off,%2.reg,%2.off}
 | |
| 
 | |
| /* Should not occur
 | |
| with exact reg_off ANYCON
 | |
| 			yields {reg_off,%1.reg,%1.off-%2.val}
 | |
| with ANYCON ADDR_EXTERN
 | |
| 			yields {ADDR_EXTERN,%2.off+%1.val}
 | |
| with exact ANYCON ADDR_LOCAL
 | |
| 			yields {ADDR_LOCAL,%1.val+%2.ind}
 | |
| */
 | |
| 
 | |
| with rm REG
 | |
|   gen sub %2,%1		yields %2
 | |
| with const ACC
 | |
|   gen sub %2,%1		yields %2
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 7 : Increment/Decrement Zero				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat inc
 | |
| with REG
 | |
| gen inc %1			yields %1
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat inl inreg($1)==reg_any
 | |
|   kills regvar($1)
 | |
|   gen inc {LOCAL,$1,4}
 | |
| #endif
 | |
| 
 | |
| pat inl
 | |
| kills indir, locals %ind + %size>$1 && %ind<$1+4
 | |
| gen inc {LOCAL,$1,4}
 | |
| 
 | |
| pat ine
 | |
| kills mem_nonlocals
 | |
| gen inc {EXTERN,$1}
 | |
| 
 | |
| pat dec
 | |
| with REG
 | |
| gen dec %1			yields %1
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat del inreg($1)==reg_any
 | |
|   kills regvar($1)
 | |
|   gen dec {LOCAL,$1,4}
 | |
| #endif
 | |
| 
 | |
| pat del
 | |
| kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
| gen dec {LOCAL, $1, 4}
 | |
| 
 | |
| pat dee
 | |
| kills mem_nonlocals
 | |
| gen dec {EXTERN, $1}
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat zrl inreg($1)==reg_any
 | |
|   kills regvar($1)
 | |
|   gen move {ANYCON, 0}, {LOCAL,$1,4}
 | |
| #endif
 | |
| 
 | |
| pat zrl
 | |
| kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
| gen move {ANYCON, 0}, {LOCAL,$1,4}
 | |
| 
 | |
| pat zre
 | |
| kills mem_nonlocals
 | |
| gen move {ANYCON, 0},  {EXTERN, $1}
 | |
| 
 | |
| pat zrf			leaving zer $1
 | |
| 
 | |
| pat zer $1==4			yields {ANYCON, 0}
 | |
| pat zer $1==8			yields {ANYCON, 0} {ANYCON, 0}
 | |
| pat zer $1==12			yields {ANYCON, 0} {ANYCON, 0}
 | |
| 				       {ANYCON, 0}
 | |
| pat zer $1==16			yields {ANYCON, 0} {ANYCON, 0}
 | |
| 				       {ANYCON, 0} {ANYCON, 0}
 | |
| 
 | |
| pat zer defined($1)
 | |
| with STACK
 | |
| gen move {ANYCON, $1/4}, ecx
 | |
|     move {ANYCON, 0}, ebx
 | |
|     1:
 | |
|     push ebx
 | |
|     loop {label,1b}
 | |
| 
 | |
| pat zer !defined($1)
 | |
| with CXREG STACK
 | |
| gen move {ANYCON, $1/4}, ebx
 | |
|     sar ecx,{ANYCON, 1}
 | |
|     1:
 | |
|     push ebx
 | |
|     loop {label,1b}
 | |
| 
 | |
| #ifdef REGVARS
 | |
| proc lolrxxxstl example lol adi stl
 | |
| with rmorconst
 | |
|   kills regvar($1)
 | |
|   gen axx* {LOCAL, $1, 4}, %1
 | |
| 
 | |
| proc lilrxxxsil example lil adi sil
 | |
| with regorconst
 | |
| kills all_mems
 | |
| gen axx* {indir_r, regvar($1)}, %1
 | |
| 
 | |
| proc xxxrstl example adi stl
 | |
| with rmorconst regorconst-RREG
 | |
|   kills regvar($2)
 | |
|   gen move %1, {LOCAL, $2, 4}
 | |
|       axx* {LOCAL, $2, 4}, %2
 | |
| 
 | |
| pat lol adi stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
 | |
| pat lol adu stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
 | |
| pat lol ads stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("add")
 | |
| pat lol and stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("and")
 | |
| pat lol ior stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("or")
 | |
| pat lol xor stl $1==$3 && $2==4 && inreg($1)==reg_any	call lolrxxxstl("xor")
 | |
| 
 | |
| pat lil adi sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
 | |
| pat lil adu sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
 | |
| pat lil ads sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("add")
 | |
| pat lil and sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("and")
 | |
| pat lil ior sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("or")
 | |
| pat lil xor sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilrxxxsil("xor")
 | |
| 
 | |
| pat adi stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
 | |
| pat adu stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
 | |
| pat ads stl $1==4 && inreg($2)==reg_any	call xxxrstl("add")
 | |
| pat and stl $1==4 && inreg($2)==reg_any	call xxxrstl("and")
 | |
| pat ior stl $1==4 && inreg($2)==reg_any	call xxxrstl("or")
 | |
| pat xor stl $1==4 && inreg($2)==reg_any	call xxxrstl("xor")
 | |
| #endif
 | |
| 
 | |
| proc lolxxxstl example lol adi stl
 | |
| with regorconst
 | |
| kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
| gen axx* {LOCAL, $1, 4}, %1
 | |
| 
 | |
| pat lol adi stl $1==$3 && $2==4		call lolxxxstl("add")
 | |
| pat lol adu stl $1==$3 && $2==4		call lolxxxstl("add")
 | |
| pat lol ads stl $1==$3 && $2==4		call lolxxxstl("add")
 | |
| pat lol and stl $1==$3 && $2==4		call lolxxxstl("and")
 | |
| pat lol ior stl $1==$3 && $2==4		call lolxxxstl("or")
 | |
| pat lol xor stl $1==$3 && $2==4		call lolxxxstl("xor")
 | |
| 
 | |
| proc lilxxxsil example lil adi sil
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={LOCAL, $1, 4}
 | |
| gen axx* {indir_r, %a}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat lil adi sil $1==$3 && $2==4		call lilxxxsil("add")
 | |
| pat lil adu sil $1==$3 && $2==4		call lilxxxsil("add")
 | |
| pat lil ads sil $1==$3 && $2==4		call lilxxxsil("add")
 | |
| pat lil and sil $1==$3 && $2==4		call lilxxxsil("and")
 | |
| pat lil ior sil $1==$3 && $2==4		call lilxxxsil("or")
 | |
| pat lil xor sil $1==$3 && $2==4		call lilxxxsil("xor")
 | |
| 
 | |
| #ifdef REGVARS
 | |
| proc lilruxxsil example lil ngi sil
 | |
| kills all_mems
 | |
| gen uxx* {indir_r, regvar($1)}
 | |
| 
 | |
| pat lil ngi sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilruxxsil("neg")
 | |
| pat lil com sil $1==$3 && $2==4 && inreg($1)==reg_any	call lilruxxsil("not")
 | |
| pat lil dec sil $1==$3 && inreg($1)==reg_any		call lilruxxsil("dec")
 | |
| pat lil inc sil $1==$3 && inreg($1)==reg_any		call lilruxxsil("inc")
 | |
| pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==1	call lilruxxsil("inc")
 | |
| pat lil adp sil $1==$3 && inreg($1)==reg_any && $2==(0-1)
 | |
| 							call lilruxxsil("dec")
 | |
| #endif
 | |
| 
 | |
| proc liluxxsil example lil ngi sil
 | |
| kills all_mems
 | |
| uses ADDREG={LOCAL, $1, 4}
 | |
| gen uxx* {indir_r, %a}
 | |
|     killreg %a
 | |
| 
 | |
| pat lil ngi sil $1==$3 && $2==4		call liluxxsil("neg")
 | |
| pat lil com sil $1==$3 && $2==4		call liluxxsil("not")
 | |
| pat lil dec sil $1==$3			call liluxxsil("dec")
 | |
| pat lil inc sil $1==$3			call liluxxsil("inc")
 | |
| pat lil adp sil $1==$3 && $2==1		call liluxxsil("inc")
 | |
| pat lil adp sil $1==$3 && $2==(0-1)	call liluxxsil("dec")
 | |
| 
 | |
| proc loexxxste example loe adi ste
 | |
| with regorconst
 | |
| kills mem_nonlocals
 | |
| gen axx* {EXTERN, $1}, %1
 | |
| 
 | |
| pat loe adi ste $1==$3 && $2==4		call loexxxste("add")
 | |
| pat loe adu ste $1==$3 && $2==4		call loexxxste("add")
 | |
| pat loe ads ste $1==$3 && $2==4		call loexxxste("add")
 | |
| pat loe and ste $1==$3 && $2==4		call loexxxste("and")
 | |
| pat loe ior ste $1==$3 && $2==4		call loexxxste("or")
 | |
| pat loe xor ste $1==$3 && $2==4		call loexxxste("xor")
 | |
| 
 | |
| #ifdef REGVARS
 | |
| proc lofrxxxsof example lol lof adi lol stf
 | |
| with regorconst
 | |
| kills all_mems
 | |
| gen axx* {indir_r_off, regvar($1), $2}, %1
 | |
| 
 | |
| pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("add")
 | |
| pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("add")
 | |
| pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("add")
 | |
| pat lol lof and lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("and")
 | |
| pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("or")
 | |
| pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofrxxxsof("xor")
 | |
| 
 | |
| proc lofruxxsof example lol lof inc lol stf
 | |
| kills all_mems
 | |
| gen uxx* {indir_r_off, regvar($1), $2}
 | |
| 
 | |
| pat lol lof inc lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
 | |
| 					call lofruxxsof("inc")
 | |
| pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==1
 | |
| 					call lofruxxsof("inc")
 | |
| pat lol lof dec lol stf $1==$4 && $2==$5 && inreg($1)==reg_any
 | |
| 					call lofruxxsof("dec")
 | |
| pat lol lof adp lol stf $1==$4 && $2==$5 && inreg($1)==reg_any && $3==(0-1)
 | |
| 					call lofruxxsof("dec")
 | |
| pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofruxxsof("neg")
 | |
| pat lol lof com lol stf $1==$4 && $2==$5 && $3==4 && inreg($1)==reg_any
 | |
| 					call lofruxxsof("not")
 | |
| 
 | |
| pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
 | |
| kills all_mems
 | |
| uses ADDREG={indir_r_off, regvar($1), $2}
 | |
| gen add {indir_r_off, regvar($1), $2}, {ANYCON, $4} 	yields %a
 | |
| 
 | |
| #endif
 | |
| 
 | |
| proc lofuxxsof example lol lof inc lol stf
 | |
| kills all_mems
 | |
| uses ADDREG={LOCAL,$1,4}
 | |
| gen uxx* {indir_r_off, %a, $2}
 | |
|     killreg %a
 | |
| 
 | |
| pat lol lof ngi lol stf $1==$4 && $2==$5 && $3==4	call lofuxxsof("neg")
 | |
| pat lol lof com lol stf $1==$4 && $2==$5 && $3==4	call lofuxxsof("not")
 | |
| pat lol lof dec lol stf $1==$4 && $2==$5		call lofuxxsof("dec")
 | |
| pat lol lof inc lol stf $1==$4 && $2==$5		call lofuxxsof("inc")
 | |
| pat lol lof adp lol stf $1==$4 && $2==$5 && $3==1	call lofuxxsof("inc")
 | |
| pat lol lof adp lol stf $1==$4 && $2==$5 && $3==(0-1)	call lofuxxsof("dec")
 | |
| 
 | |
| proc lofxxxsof example lol lof adi lol stf
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={LOCAL,$1,4}
 | |
| gen axx* {indir_r_off, %a, $2}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat lol lof adi lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
 | |
| pat lol lof adu lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
 | |
| pat lol lof ads lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("add")
 | |
| pat lol lof and lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("and")
 | |
| pat lol lof ior lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("or")
 | |
| pat lol lof xor lol stf $1==$4 && $2==$5 && $3==4	call lofxxxsof("xor")
 | |
| 
 | |
| pat lol lof dup adp lol stf $1==$5 && $2==$6 && $3==4
 | |
| kills all_mems
 | |
| uses ADDREG={LOCAL,$1,4},ADDREG
 | |
| gen mov %b, {indir_r_off, %a, $2}
 | |
|     add {indir_r_off, %a, $2}, {ANYCON, $4}
 | |
|     killreg %a				yields %b
 | |
| 
 | |
| proc lefuxxsef example loe lof inc loe stf
 | |
| kills all_mems
 | |
| uses ADDREG={EXTERN,$1}
 | |
| gen uxx* {indir_r_off, %a, $2}
 | |
|     killreg %a
 | |
| 
 | |
| pat loe lof ngi loe stf $1==$4 && $2==$5 && $3==4	call lefuxxsef("neg")
 | |
| pat loe lof com loe stf $1==$4 && $2==$5 && $3==4	call lefuxxsef("not")
 | |
| pat loe lof dec loe stf $1==$4 && $2==$5		call lefuxxsef("dec")
 | |
| pat loe lof inc loe stf $1==$4 && $2==$5		call lefuxxsef("inc")
 | |
| pat loe lof adp loe stf $1==$4 && $2==$5 && $3==1	call lefuxxsef("inc")
 | |
| pat loe lof adp loe stf $1==$4 && $2==$5 && $3==(0-1)	call lefuxxsef("dec")
 | |
| 
 | |
| proc lefxxxsef example loe lof adi loe stf
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={EXTERN,$1}
 | |
| gen axx* {indir_r_off, %a, $2}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat loe lof adi loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
 | |
| pat loe lof adu loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
 | |
| pat loe lof ads loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("add")
 | |
| pat loe lof and loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("and")
 | |
| pat loe lof ior loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("or")
 | |
| pat loe lof xor loe stf $1==$4 && $2==$5 && $3==4	call lefxxxsef("xor")
 | |
| 
 | |
| pat loe lof dup adp loe stf $1==$5 && $2==$6 && $3==4
 | |
| kills all_mems
 | |
| uses ADDREG={EXTERN,$1},ADDREG
 | |
| gen mov %b, {indir_r_off, %a, $2}
 | |
|     add {indir_r_off, %a, $2}, {ANYCON, $4}
 | |
|     killreg %a				yields %b
 | |
| 
 | |
| proc leiuxxsei example loe loi inc loe sti
 | |
| kills all_mems
 | |
| uses ADDREG={EXTERN,$1}
 | |
| gen uxx* {indir_r, %a}
 | |
|     killreg %a
 | |
| 
 | |
| pat loe loi ngi loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leiuxxsei("neg")
 | |
| pat loe loi com loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leiuxxsei("not")
 | |
| pat loe loi dec loe sti $1==$4 && $2==4 && $5==4
 | |
| 	call leiuxxsei("dec")
 | |
| pat loe loi inc loe sti $1==$4 && $2==4 && $5==4
 | |
| 	call leiuxxsei("inc")
 | |
| pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==1
 | |
| 	call leiuxxsei("inc")
 | |
| pat loe loi adp loe sti $1==$4 && $2==4 && $5==4 && $3==(0-1)
 | |
| 	call leiuxxsei("dec")
 | |
| 
 | |
| proc leixxxsei example loe loi adi loe sti
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={EXTERN,$1}
 | |
| gen axx* {indir_r, %a}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat loe loi adi loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("add")
 | |
| pat loe loi adu loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("add")
 | |
| pat loe loi ads loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("add")
 | |
| pat loe loi and loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("and")
 | |
| pat loe loi ior loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("or")
 | |
| pat loe loi xor loe sti $1==$4 && $2==4 && $5==4 && $3==4
 | |
| 	call leixxxsei("xor")
 | |
| 
 | |
| #ifdef REGVARS
 | |
| proc lifuxxsif example lil lof inc lil stf
 | |
| kills all_mems
 | |
| uses ADDREG={indir_r,regvar($1)}
 | |
| gen uxx* {indir_r_off, %a, $2}
 | |
|     killreg %a
 | |
| 
 | |
| pat lil lof ngi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifuxxsif("neg")
 | |
| pat lil lof com lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifuxxsif("not")
 | |
| pat lil lof dec lil stf $1==$4 && $2==$5 && inreg($1)>0
 | |
| 	call lifuxxsif("dec")
 | |
| pat lil lof inc lil stf $1==$4 && $2==$5 && inreg($1)>0
 | |
| 	call lifuxxsif("inc")
 | |
| 
 | |
| proc lifxxxsif example lil lof adi lil stf
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={indir_r,regvar($1)}
 | |
| gen axx* {indir_r_off, %a, $2}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat lil lof adi lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("add")
 | |
| pat lil lof adu lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("add")
 | |
| pat lil lof ads lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("add")
 | |
| pat lil lof and lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("and")
 | |
| pat lil lof ior lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("or")
 | |
| pat lil lof xor lil stf $1==$4 && $2==$5 && $3==4 && inreg($1)>0
 | |
| 	call lifxxxsif("xor")
 | |
| 
 | |
| proc liiuxxsii example lil loi inc lil sti
 | |
| kills all_mems
 | |
| uses ADDREG={indir_r,regvar($1)}
 | |
| gen uxx* {indir_r, %a}
 | |
|     killreg %a
 | |
| 
 | |
| pat lil loi ngi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liiuxxsii("neg")
 | |
| pat lil loi com lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liiuxxsii("not")
 | |
| pat lil loi dec lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
 | |
| 	call liiuxxsii("dec")
 | |
| pat lil loi inc lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0
 | |
| 	call liiuxxsii("inc")
 | |
| pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==1
 | |
| 	call liiuxxsii("inc")
 | |
| pat lil loi adp lil sti $1==$4 && $2==4 && $5==4 && inreg($1)>0 && $3==(0-1)
 | |
| 	call liiuxxsii("dec")
 | |
| 
 | |
| proc liixxxsii example lil loi adi lil sti
 | |
| with regorconst
 | |
| kills all_mems
 | |
| uses ADDREG={indir_r,regvar($1)}
 | |
| gen axx* {indir_r, %a}, %1
 | |
|     killreg %a
 | |
| 
 | |
| pat lil loi adi lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("add")
 | |
| pat lil loi adu lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("add")
 | |
| pat lil loi ads lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("add")
 | |
| pat lil loi and lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("and")
 | |
| pat lil loi ior lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("or")
 | |
| pat lil loi xor lil sti $1==$4 && $2==4 && $5==4 && $3==4 && inreg($1)>0
 | |
| 	call liixxxsii("xor")
 | |
| 
 | |
| proc lolcrxxstl example lol loc sbi stl
 | |
|   kills regvar($1)
 | |
|   gen axx* {LOCAL,$1,4},{ANYCON,$2}
 | |
| 
 | |
| pat lol loc sbi stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("sub")
 | |
| pat lol loc sbu stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("sub")
 | |
| pat lol loc sli stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("sal")
 | |
| pat lol loc slu stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("sal")
 | |
| pat lol loc sri stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("sar")
 | |
| pat lol loc sru stl $1==$4 && $3==4 && inreg($1)==reg_any
 | |
| 						call lolcrxxstl("shr")
 | |
| #endif
 | |
| 
 | |
| proc lolcxxstl example lol loc sbi stl
 | |
|   kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
|   gen axx* {LOCAL,$1,4},{ANYCON,$2}
 | |
| 
 | |
| pat lol loc sbi stl $1==$4 && $3==4		call lolcxxstl("sub")
 | |
| pat lol loc sbu stl $1==$4 && $3==4		call lolcxxstl("sub")
 | |
| pat lol loc adi stl $1==$4 && $3==4		call lolcxxstl("add")
 | |
| pat lol loc adi stl $1==$4 && $3==4		call lolcxxstl("add")
 | |
| pat lol loc sli stl $1==$4 && $3==4		call lolcxxstl("sal")
 | |
| pat lol loc slu stl $1==$4 && $3==4		call lolcxxstl("sal")
 | |
| pat lol loc sri stl $1==$4 && $3==4		call lolcxxstl("sar")
 | |
| pat lol loc sru stl $1==$4 && $3==4		call lolcxxstl("shr")
 | |
| 
 | |
| proc loecxxste example loe loc sbi ste
 | |
|   kills mem_nonlocals
 | |
|   gen axx* {EXTERN,$1},{ANYCON,$2}
 | |
| 
 | |
| pat loe loc sbi ste $1==$4 && $3==4		call loecxxste("sub")
 | |
| pat loe loc sbu ste $1==$4 && $3==4		call loecxxste("sub")
 | |
| pat loe loc adu ste $1==$4 && $3==4		call loecxxste("add")
 | |
| pat loe loc adi ste $1==$4 && $3==4		call loecxxste("add")
 | |
| pat loe loc sli ste $1==$4 && $3==4		call loecxxste("sal")
 | |
| pat loe loc slu ste $1==$4 && $3==4		call loecxxste("sal")
 | |
| pat loe loc sri ste $1==$4 && $3==4		call loecxxste("sar")
 | |
| pat loe loc sru ste $1==$4 && $3==4		call loecxxste("shr")
 | |
| 
 | |
| #ifdef REGVARS
 | |
| proc lilcxxsil example lil loc sbi sil
 | |
|   kills mem_nonlocals
 | |
|   gen axx* {indir_r,regvar($1)},{ANYCON,$2}
 | |
| 
 | |
| pat lil loc sbi sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sub")
 | |
| pat lil loc sbu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sub")
 | |
| pat lil loc adu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("add")
 | |
| pat lil loc adi sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("add")
 | |
| pat lil loc sli sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sal")
 | |
| pat lil loc slu sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sal")
 | |
| pat lil loc sri sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("sar")
 | |
| pat lil loc sru sil $1==$4 && $3==4 && inreg($1)>0	call lilcxxsil("shr")
 | |
| 
 | |
| pat lol ngi stl $1==$3 && $2==4 && inreg($1)==reg_any
 | |
| kills regvar($1)
 | |
| gen neg {LOCAL, $1, 4}
 | |
| #endif
 | |
| 
 | |
| pat lol ngi stl $1==$3 && $2==4
 | |
| kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
| gen neg {LOCAL, $1, 4}
 | |
| 
 | |
| pat lol dup adp stl loi stl $1==$4 && $2==4 && $5<=4
 | |
| 					leaving lol $1 loi $5 stl $6 lol $1 adp $3 stl $4
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==1 && inreg($1) > 0 && $6==1 && $7==4
 | |
| uses REG
 | |
| gen movsxb %a,{indir_r1, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lol $1 adp $3 stl $4
 | |
| 
 | |
| pat lol dup adp stl loi $1==$4 && $2==4 && $5==1 && inreg($1) > 0
 | |
| uses REG1 = {indir_r1, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lol $1 adp $3 stl $4
 | |
| 
 | |
| pat lol dup adp stl loi loc loc cii $1==$4 && $2==4 && $5==2 && inreg($1) > 0 && $6==2 && $7==4
 | |
| uses REG
 | |
| gen movsx %a,{indir_r2, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lol $1 adp $3 stl $4
 | |
| 
 | |
| pat lol dup adp stl loi $1==$4 && $2==4 && $5==2 && inreg($1) > 0
 | |
| uses REG2 = {indir_r2, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lol $4 adp $3 stl $4
 | |
| 
 | |
| pat lol dup adp stl loi $1==$4 && $2==4 && $5==4 && inreg($1) > 0
 | |
| uses REG = {indir_r, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lol $4 adp $3 stl $4
 | |
| pat adp stl inreg($2) > 0		leaving stl $2 lol $2 adp $1 stl $2
 | |
| #endif
 | |
| 
 | |
| pat lol dup adp stl $1==$4 && $2==4
 | |
| uses ADDREG={LOCAL,$1,4}	yields %a
 | |
| 					leaving lol $4 adp $3 stl $4
 | |
| 
 | |
| pat lol inl $1==$2
 | |
| uses REG={LOCAL,$1,4}		yields %a
 | |
| 					leaving inl $1
 | |
| 
 | |
| pat lol del $1==$2
 | |
| uses REG={LOCAL,$1,4}		yields %a
 | |
| 					leaving del $1
 | |
| 
 | |
| pat lol adp stl $1==$3 && $2==1		leaving inl $1
 | |
| pat lol adp stl $1==$3 && $2==0-1	leaving del $1
 | |
| pat lol adp stl $1==$3			leaving loc $2 lol $1 adi 4 stl $3
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lol com stl $1==$3 && $2==4 && inreg($1)==reg_any
 | |
| kills regvar($1)
 | |
| gen not {LOCAL,$1,4}
 | |
| #endif
 | |
| 
 | |
| pat lol com stl $1==$3 && $2==4
 | |
| kills indir, locals %ind+%size>$1 && %ind<$1+4
 | |
| gen not {LOCAL, $1, 4}
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lil dup adp sil $1==$4 && $2==4 && inreg($1)==reg_any
 | |
| uses ADDREG={indir_r, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lil $4 adp $3 sil $4
 | |
| 
 | |
| pat lil dup inc sil $1==$4 && $2==4 && inreg($1)==reg_any
 | |
| uses REG={indir_r, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lil $4 inc sil $4
 | |
| 
 | |
| pat lil dup dec sil $1==$4 && $2==4 && inreg($1)==reg_any
 | |
| uses REG={indir_r, regvar($1)}
 | |
| 				yields %a
 | |
| 					leaving lil $4 dec sil $4
 | |
| #endif
 | |
| 
 | |
| pat lil adp sil $1==$3 && $2==1         leaving lil $1 inc sil $1
 | |
| 
 | |
| pat lil adp sil $1==$3 && $2==0-1       leaving lil $1 dec sil $1
 | |
| 
 | |
| pat lil adp sil $1==$3			leaving loc $2 lil $1 adi 4 sil $3
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lol lof lol lof adp lol stf
 | |
| 	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
 | |
| uses ADDREG={indir_r_off, regvar($1), $2}
 | |
| 				yields %a
 | |
| 					leaving lol $1 lof $2 adp $5 lol $6 stf $7
 | |
| 
 | |
| pat lol lof lol lof inc lol stf
 | |
| 	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
 | |
| uses REG={indir_r_off, regvar($1), $2}
 | |
| 				yields %a
 | |
| 					leaving lol $1 lof $2 inc lol $6 stf $7
 | |
| 
 | |
| pat lol lof lol lof dec lol stf
 | |
| 	$1==$3 && $1==$6 && $2==$4 && $2==$7 && inreg($1)==reg_any
 | |
| uses REG={indir_r_off, regvar($1), $2}
 | |
| 				yields %a
 | |
| 					leaving lol $1 lof $2 dec lol $6 stf $7
 | |
| 
 | |
| pat lol lof dup adp lol stf
 | |
|         $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
 | |
| uses REG={indir_r_off, regvar($1), $2}
 | |
|                                 yields %a
 | |
|                                         leaving lol $1 lof $2 adp $4 lol $1 stf
 | |
| $2
 | |
| 
 | |
| pat lol lof dup inc lol stf
 | |
|         $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
 | |
| uses REG={indir_r_off, regvar($1), $2}
 | |
|                                 yields %a
 | |
|                                         leaving lol $1 lof $2 inc lol $1 stf $2
 | |
| 
 | |
| pat lol lof dup dec lol stf
 | |
|         $1==$5 && $2==$6 && $3==4 && inreg($1)==reg_any
 | |
| uses REG={indir_r_off, regvar($1), $2}
 | |
|                                 yields %a
 | |
|                                         leaving lol $1 lof $2 dec lol $1 stf $2
 | |
| 
 | |
| #endif
 | |
| 
 | |
| pat lol lof adp lol stf $1==$4 && $2==$5
 | |
| 			leaving loc $3 lol $1 lof $2 adi 4 lol $4 stf $5
 | |
| 
 | |
| pat lol lof dup adp lol stf
 | |
|         $1==$5 && $2==$6 && $3==4 && $4==1
 | |
| kills all_mems
 | |
| uses REG={LOCAL,$1,4}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     inc {indir_r_off, %a, $2}
 | |
|                                 yields %b
 | |
| 
 | |
| pat loe lof dup adp loe stf
 | |
|         $1==$5 && $2==$6 && $3==4 && $4==1
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     inc {indir_r_off, %a, $2}
 | |
|                                 yields %b
 | |
| 
 | |
| pat loe loi dup adp loe sti
 | |
|         $1==$5 && $2==$6 && $3==4 && $2==4 && $4==1
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r, %a},%b
 | |
|     inc {indir_r, %a}
 | |
|                                 yields %b
 | |
| 
 | |
| pat lol lof dup adp lol stf
 | |
|         $1==$5 && $2==$6 && $3==4 && $4==(0-1)
 | |
| kills all_mems
 | |
| uses REG={LOCAL,$1,4}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     dec {indir_r_off, %a, $2}
 | |
|                                 yields %b
 | |
| 
 | |
| pat loe lof dup adp loe stf
 | |
|         $1==$5 && $2==$6 && $3==4 && $4==(0-1)
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     dec {indir_r_off, %a, $2}
 | |
|                                 yields %b
 | |
| pat loe loi dup adp loe sti
 | |
|         $1==$5 && $2==$6 && $3==4 && $2==4 && $4==(0-1)
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r, %a},%b
 | |
|     dec {indir_r, %a}
 | |
|                                 yields %b
 | |
| 
 | |
| pat lol lof dup adp lol stf
 | |
|         $1==$5 && $2==$6 && $3==4
 | |
| kills all_mems
 | |
| uses REG={LOCAL,$1,4}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     add {indir_r_off, %a, $2}, {ANYCON, $4}
 | |
|                                 yields %b
 | |
| 
 | |
| pat loe lof dup adp loe stf
 | |
|         $1==$5 && $2==$6 && $3==4
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r_off, %a, $2},%b
 | |
|     add {indir_r_off, %a, $2}, {ANYCON, $4}
 | |
|                                 yields %b
 | |
| 
 | |
| pat loe loi dup adp loe sti
 | |
|         $1==$5 && $2==$6 && $3==4 && $2==4
 | |
| kills all_mems
 | |
| uses REG={EXTERN,$1}, REG
 | |
| gen move {indir_r, %a},%b
 | |
|     add {indir_r, %a}, {ANYCON, $4}
 | |
|                                 yields %b
 | |
| 
 | |
| 
 | |
| pat loe ngi ste $1==$3 && $2==4
 | |
| kills mem_nonlocals
 | |
| gen neg {EXTERN, $1}
 | |
| 
 | |
| pat loe dup adp ste $1==$4 && $2==4
 | |
| uses REG={EXTERN,$1}	yields %a
 | |
| 					leaving loe $1 adp $3 ste $1
 | |
| 
 | |
| pat loe ine $1==$2
 | |
| uses REG={EXTERN,$1}	yields %a
 | |
| 					leaving ine $1
 | |
| 
 | |
| pat loe dee $1==$2
 | |
| uses REG={EXTERN,$1}	yields %a
 | |
| 					leaving dee $1
 | |
| 
 | |
| pat loe adp ste $1==$3 && $2==1		leaving ine $1
 | |
| 
 | |
| pat loe adp ste $1==$3 && $2==0-1	leaving dee $1
 | |
| 
 | |
| pat loe adp ste $1==$3			leaving loc $2 loe $1 adi 4 ste $3
 | |
| 
 | |
| pat loe com ste $1==$3 && $2==4
 | |
| kills mem_nonlocals
 | |
| gen not {EXTERN, $1}
 | |
| 
 | |
| pat loe lof adp loe stf $1==$4 && $2==$5
 | |
| 				leaving loc $3 loe $1 lof $2 adi 4 loe $1 stf $2
 | |
| 
 | |
| pat loe loi adp loe sti $1==$4 && $2==$5 && $2==4
 | |
| 				leaving loc $3 loe $1 loi $2 adi 4 loe $1 sti $2
 | |
| 
 | |
| pat lil lof adp lil stf $1==$4 && $2==$5 && $3==1
 | |
| 				leaving lil $1 lof $2 inc lil $1 stf $2
 | |
| pat lil lof adp lil stf $1==$4 && $2==$5 && $3==0-1
 | |
| 				leaving lil $1 lof $2 dec lil $1 stf $2
 | |
| pat lil lof adp lil stf $1==$4 && $2==$5
 | |
| 				leaving loc $3 lil $1 lof $2 adi 4 lil $1 stf $2
 | |
| pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==1
 | |
| 				leaving lil $1 loi $2 inc lil $1 sti $2
 | |
| pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4 && $3==0-1
 | |
| 				leaving lil $1 loi $2 dec lil $1 sti $2
 | |
| pat lil loi adp lil sti $1==$4 && $2==$5 && $2==4
 | |
| 				leaving loc $3 lil $1 loi $2 adi 4 lil $1 sti $2
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 8: Convert Instructions				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat cii
 | |
| with CXREG DXREG ACC
 | |
| kills ALL
 | |
| gen proccall {label,".cii"}		yields %3
 | |
| 
 | |
| pat ciu					leaving cuu
 | |
| pat cui					leaving cuu
 | |
| 
 | |
| pat cuu
 | |
| 
 | |
| pat loc loc cii zeq $1==1
 | |
| with GENREG STACK
 | |
| gen test %1.1
 | |
|     je {label, $4}
 | |
| 
 | |
| pat loc loc cii zne $1==1
 | |
| with GENREG STACK
 | |
| gen test %1.1
 | |
|     jne {label, $4}
 | |
| 
 | |
| pat loc loc cii loc and zeq $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
 | |
| 		leaving loc $4 and $5 zeq $6
 | |
| pat loc loc cii loc and zne $4<256 && $4>=0 && $5==4 && $1==1 && $2==4
 | |
| 		leaving loc $4 and $5 zne $6
 | |
| pat loc loc cii loc and zeq $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
 | |
| 		leaving loc $4 and $5 zeq $6
 | |
| pat loc loc cii loc and zne $4<65536 && $4>=0 && $5==4 && $1==2 && $2==4
 | |
| 		leaving loc $4 and $5 zne $6
 | |
| 
 | |
| pat loc loc cii $1==1 && $2==4
 | |
| with ACC
 | |
| gen movsxb %1,%1		yields eax
 | |
| with exact rm1
 | |
| uses reusing %1, GENREG
 | |
| gen movsxb %a,%1		yields %a
 | |
| 
 | |
| pat loc loc cii $1==2 && $2==4
 | |
| with ACC
 | |
| gen  movsx %1,%1		yields eax
 | |
| with exact rm2
 | |
| uses reusing %1,GENREG
 | |
| gen movsx %a,%1			yields %a
 | |
| 
 | |
| pat loc loc ciu				leaving loc $1 loc $2 cuu
 | |
| pat loc loc cui				leaving loc $1 loc $2 cuu
 | |
| 
 | |
| pat loc loc cuu $1==$2
 | |
| 
 | |
| pat loc loc cif $1==4 && $2==4		leaving loc 4 cal ".cif4" asp 4
 | |
| pat loc loc cif $1==4 && $2==8		leaving loc 4 cal ".cif8"
 | |
| pat loc loc cuf $1==4 && $2==4		leaving loc 4 cal ".cuf4" asp 4
 | |
| pat loc loc cuf $1==4 && $2==8		leaving loc 4 cal ".cuf8"
 | |
| pat loc loc cfi		leaving loc $1 loc $2 cal ".cfi" asp 8+($1-4)
 | |
| pat loc loc cfu		leaving loc $1 loc $2 cal ".cfu" asp 8+($1-4)
 | |
| pat loc loc cff $1==8 && $2==4	leaving cal ".cff4" asp 4
 | |
| pat loc loc cff $1==4 && $2==8
 | |
| with REG
 | |
| kills ALL
 | |
|   gen push {ANYCON,0}
 | |
|       push %1			leaving cal ".cff8"
 | |
| 
 | |
| /********************************************************************
 | |
|  *  Group 9 : Logical Instructions				    *
 | |
|  ********************************************************************/
 | |
| 
 | |
| pat and $1==4
 | |
| with REG rmorconst
 | |
|   gen and %1,%2				yields %1
 | |
| with rmorconst REG
 | |
|   gen and %2,%1				yields %2
 | |
| 
 | |
| pat loc and $1==255 && $2==4
 | |
| with GENREG				yields %1.1
 | |
| 
 | |
| pat and $1==8
 | |
| with EXACT REG REG rmorconst rmorconst
 | |
|   gen and %1,%3
 | |
|       and %2,%4				yields %2 %1
 | |
| with rmorconst rmorconst REG REG
 | |
|   gen and %3,%1
 | |
|       and %4,%2				yields %4 %3
 | |
| 
 | |
| pat and defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".and"}
 | |
| 
 | |
| pat and !defined($1)
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label, ".and"}
 | |
| 
 | |
| pat ior $1==4
 | |
| with REG rmorconst
 | |
|   gen or %1,%2				yields %1
 | |
| with rmorconst REG
 | |
|   gen or %2,%1				yields %2
 | |
| 
 | |
| pat ior $1==8
 | |
| with EXACT REG REG rmorconst rmorconst
 | |
|   gen or %1,%3
 | |
|       or %2,%4				yields %2 %1
 | |
| with rmorconst rmorconst REG REG
 | |
|   gen or %3,%1
 | |
|       or %4,%2				yields %4 %3
 | |
| 
 | |
| pat ior defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".ior"}
 | |
| 
 | |
| pat ior !defined($1)
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label, ".ior"}
 | |
| 
 | |
| pat xor $1==4
 | |
| with REG rmorconst
 | |
|   gen xor %1,%2				yields %1
 | |
| with rmorconst REG
 | |
|   gen xor %2,%1				yields %2
 | |
| 
 | |
| pat xor $1==8
 | |
| with EXACT REG REG rmorconst rmorconst
 | |
|   gen xor %1,%3
 | |
|       xor %2,%4				yields %2 %1
 | |
| with rmorconst rmorconst REG REG
 | |
|   gen xor %3,%1
 | |
|       xor %4,%2				yields %4 %3
 | |
| 
 | |
| pat xor defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".xor"}
 | |
| 
 | |
| pat xor !defined($1)
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label, ".xor"}
 | |
| 
 | |
| pat com $1==4
 | |
| with REG
 | |
|   gen not %1				yields %1
 | |
| 
 | |
| pat com $1==8
 | |
| with REG REG
 | |
|   gen not %2
 | |
|       not %1				yields %2 %1
 | |
| 
 | |
| pat com defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".com"}
 | |
| 
 | |
| pat com !defined($1)
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label, ".com"}
 | |
| 
 | |
| pat rol $1==4
 | |
| with SHIFT_CREG REG
 | |
|   gen rol %2,cl				yields %2
 | |
| with ANYCON REG
 | |
|   gen rol %2,%1				yields %2
 | |
| 
 | |
| pat ror $1==4
 | |
| with SHIFT_CREG REG
 | |
|   gen ror %2,cl				yields %2
 | |
| with ANYCON REG
 | |
|   gen ror %2,%1				yields %2
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 10 : Set Instructions					   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat inn $1==4
 | |
| with SHIFT_CREG REG
 | |
| gen shr %2,cl
 | |
|     and %2,{ANYCON, 1}			yields %2
 | |
| with ANYCON REG
 | |
| gen shr %2,%1
 | |
|     and %2,{ANYCON, 1}			yields %2
 | |
| 
 | |
| pat loc inn $1==0 && $2==4
 | |
| with REG
 | |
| gen and %1,{ANYCON, 1}			yields %1
 | |
| 
 | |
| pat inn defined($1)
 | |
| with ACC
 | |
| kills ALL
 | |
| gen mov ecx,{ANYCON, $1}
 | |
|     proccall {label,".inn"}		yields eax
 | |
| 
 | |
| pat inn !defined($1)
 | |
| with CXREG ACC
 | |
| kills ALL
 | |
| gen proccall {label,".inn"}		yields eax
 | |
| 
 | |
| pat loc inn zeq $2==4
 | |
| with rm STACK
 | |
| gen check %1,{ANYCON,1<<$1}
 | |
|     je {label,$3}
 | |
| 
 | |
| pat loc inn zne $2==4
 | |
| with rm STACK
 | |
| gen check %1,{ANYCON,1<<$1}
 | |
|     jne {label,$3}
 | |
| 
 | |
| pat set $1==4
 | |
| with SHIFT_CREG
 | |
| uses REG={ANYCON, 1}
 | |
| gen shl %a,cl			yields %a
 | |
| 
 | |
| pat set defined($1)
 | |
| with ACC
 | |
| kills ALL
 | |
| gen mov ecx,{ANYCON, $1}
 | |
|     proccall {label,".set"}
 | |
| 
 | |
| pat set !defined($1)
 | |
| with CXREG ACC
 | |
| kills ALL
 | |
| gen proccall {label,".set"}
 | |
| 
 | |
| /********************************************************************
 | |
|  *  Group 11 : Array Instructions				    *
 | |
|  ********************************************************************/
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)==0
 | |
| 				leaving ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==1 && rom($1,1)!=0
 | |
| 				leaving adp 0-rom($1,1) ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)==0
 | |
| 				leaving loc 1 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==2 && rom($1,1)!=0
 | |
| 				leaving adp 0-rom($1,1) loc 1 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
 | |
| 				leaving loc 2 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
 | |
| 				leaving adp 0-rom($1,1) loc 2 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)==0
 | |
| 				leaving loc 3 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,3)==8 && rom($1,1)!=0
 | |
| 				leaving adp 0-rom($1,1) loc 3 sli 4 ads 4
 | |
| 
 | |
| pat lae aar $2==4 && rom($1,1)==0
 | |
|   with ADDREG
 | |
|   gen imul %1,%1,{ANYCON,rom($1,3)}	yields %1	leaving ads 4
 | |
| 
 | |
| pat lae aar $2==4 && defined(rom($1,1))
 | |
|   with ADDREG
 | |
|   gen imul %1,%1,{ANYCON,rom($1,3)}	yields %1
 | |
| 				leaving adp 0-rom($1,1)*rom($1,3) ads 4
 | |
| 
 | |
| /* when followed by an LOI or STI instruction, use indexed mode */
 | |
| pat loc sli ads loi ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
 | |
| with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
 | |
| 					leaving loi $4
 | |
| with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
 | |
| 					leaving loi $4
 | |
| with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
 | |
| 					leaving loi $4
 | |
| 
 | |
| pat loc sli ads sti ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
 | |
| with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
 | |
| 					leaving sti $4
 | |
| with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
 | |
| 					leaving sti $4
 | |
| with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
 | |
| 					leaving sti $4
 | |
| 
 | |
| pat loc sli ads ($1==1 || $1==2 || $1==3) && $2==4 && $3==4
 | |
| with IREG ADDR_LOCAL		yields {indexed_r_off,ebp,%1,1<<$1,%2.ind}
 | |
| with IREG ADDR_EXTERN		yields {indexed_off,%1,1<<$1,%2.off}
 | |
| with IREG ADDREG		yields {indexed_r_off,%2,%1,1<<$1,0}
 | |
| with REG rmorconst
 | |
| gen sal %1,{ANYCON,$1}		yields %2 %1	leaving ads 4
 | |
| 
 | |
| pat aar $1==4
 | |
|   with AREG REG
 | |
|   gen sub %2,{indir_r,%1}
 | |
|       imul %2,{indir_r_off,%1,8}		yields %2	leaving ads 4
 | |
|   with reg_off REG
 | |
|   gen sub %2,{indir_r_off, %1.reg, %1.off}
 | |
|       imul %2,{indir_r_off, %1.reg, 8+%1.off}
 | |
| 					yields %2	leaving ads 4
 | |
|   with ADDR_LOCAL REG
 | |
|   gen sub %2,{LOCAL,%1.ind,4}
 | |
|       imul %2,{LOCAL,8+%1.ind,4}	yields %2	leaving ads 4
 | |
|   with ADDR_EXTERN REG
 | |
|   gen sub %2,{EXTERN,%1.off}
 | |
|       imul %2,{EXTERN,8+%1.off}		yields %2	leaving ads 4
 | |
| 
 | |
| pat lae lar defined(rom($1,3))	leaving lae $1 aar $2 loi rom($1,3)
 | |
| 
 | |
| pat lae sar defined(rom($1,3))	leaving lae $1 aar $2 sti rom($1,3)
 | |
| 
 | |
| pat aar !defined($1)
 | |
|   kills ALL
 | |
|   gen proccall {label,".iaar"}		yields ebx
 | |
| 
 | |
| pat sar $1==4
 | |
|   with BXREG ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".sar4"}
 | |
| 
 | |
| pat sar !defined($1)
 | |
|   kills ALL
 | |
|   gen proccall {label,".isar"}
 | |
| 
 | |
| pat lar $1==4
 | |
|   with BXREG ACC
 | |
|   kills ALL
 | |
|   gen proccall {label,".lar4"}
 | |
| 
 | |
| pat lar !defined($1)
 | |
|   kills ALL
 | |
|   gen proccall {label,".ilar"}
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 12 : Compare Instructions				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat cmi $1==4
 | |
| with register rmorconst
 | |
|   uses REG={ANYCON,0}
 | |
|   gen cmp %1,%2
 | |
|       je {label,2f}
 | |
|       jl {label,1f}
 | |
|       inc %a
 | |
|       jmp {label,2f}
 | |
|       1:
 | |
|       dec %a
 | |
|       2:			yields %a
 | |
| with rmorconst register
 | |
|   uses REG={ANYCON,0}
 | |
|   gen cmp %2,%1
 | |
|       je {label,2f}
 | |
|       jg {label,1f}
 | |
|       inc %a
 | |
|       jmp {label,2f}
 | |
|       1:
 | |
|       dec %a
 | |
|       2:			yields %a
 | |
| 
 | |
| pat cmu $1==4				 leaving cmp
 | |
| 
 | |
| pat cms $1==4
 | |
| with REG rmorconst
 | |
|   gen sub %1,%2			yields %1
 | |
| with rmorconst REG
 | |
|   gen sub %2,%1			yields %2
 | |
| 
 | |
| pat cms $1==8
 | |
| with rmorconst rmorconst REG REG
 | |
|   gen sub %3,%1
 | |
|       sbb %4,%2
 | |
|       or %4,%3			yields %4
 | |
| with REG REG rmorconst rmorconst
 | |
|   gen sub %1,%3
 | |
|       sbb %2,%4
 | |
|       or %2,%1			yields %2
 | |
| 
 | |
| pat cms defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label,".cms"}	yields ecx
 | |
| 
 | |
| pat cms !defined($1)
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label,".cms"}	yields ecx
 | |
| 
 | |
| pat cmf $1==4
 | |
| kills ALL
 | |
|   gen proccall {label,".cmf4"}	leaving asp 8 lfr 4
 | |
| 
 | |
| pat cmf $1==8
 | |
| kills ALL
 | |
|   gen proccall {label,".cmf8"}	leaving asp 16 lfr 4
 | |
| 
 | |
| pat cmp
 | |
| with register rmorconst
 | |
| uses REG = {ANYCON,0}
 | |
|   gen cmp %1,%2
 | |
|       je  {label,2f}
 | |
|       jb  {label,1f}
 | |
|       inc %a
 | |
|       jmp {label,2f}
 | |
|       1: dec %a
 | |
|       2:			    yields %a
 | |
| with rmorconst register
 | |
| uses REG = {ANYCON,0}
 | |
|   gen cmp %2,%1
 | |
|       je  {label,2f}
 | |
|       ja  {label,1f}
 | |
|       inc %a
 | |
|       jmp {label,2f}
 | |
|       1: dec %a
 | |
|       2:			    yields %a
 | |
| 
 | |
| proc txx
 | |
| with rm
 | |
| uses GENREG = {ANYCON,0}
 | |
|   gen test %1
 | |
|       setxx* %a.1		    yields %a
 | |
| 
 | |
| pat tlt call txx("sets")
 | |
| pat teq call txx("sete")
 | |
| pat tne call txx("setne")
 | |
| pat tge call txx("setns")
 | |
| 
 | |
| /* Explicit test for TLE and TGT. We must make sure that the OC
 | |
|    flag is cleared.
 | |
| */
 | |
| pat tle
 | |
| with rm
 | |
| uses GENREG = {ANYCON,0}
 | |
|   gen
 | |
|       killcc.
 | |
|       test %1
 | |
|       setle %a.1
 | |
| 				   yields %a
 | |
| 
 | |
| pat tgt
 | |
| with rm
 | |
| uses GENREG = {ANYCON,0}
 | |
|   gen
 | |
|       killcc.
 | |
|       test %1
 | |
|       setg %a.1
 | |
| 				   yields %a
 | |
| 
 | |
| proc txxior
 | |
| with rm REG
 | |
|   gen test %1
 | |
|       jxx* {label,1f}
 | |
|       or  %2,{ANYCON,1}
 | |
|       1:			    yields %2
 | |
| 
 | |
| pat tlt ior $2==4 call txxior("jge")
 | |
| pat tle ior $2==4 call txxior("jg")
 | |
| pat teq ior $2==4 call txxior("jne")
 | |
| pat tne ior $2==4 call txxior("je")
 | |
| pat tge ior $2==4 call txxior("jl")
 | |
| pat tgt ior $2==4 call txxior("jle")
 | |
| 
 | |
| proc cmixxior
 | |
| with regorconst rm REG
 | |
|   gen cmp %2,%1
 | |
|       jxx* {label,1f}
 | |
|       or  %3,{ANYCON,1}
 | |
|       1:			    yields %3
 | |
| 
 | |
| pat cmi tlt ior $1==4 && $3==4 call cmixxior("jge")
 | |
| pat cmi tle ior $1==4 && $3==4 call cmixxior("jg")
 | |
| pat cmi teq ior $1==4 && $3==4 call cmixxior("jne")
 | |
| pat cmi tne ior $1==4 && $3==4 call cmixxior("je")
 | |
| pat cmi tge ior $1==4 && $3==4 call cmixxior("jl")
 | |
| pat cmi tgt ior $1==4 && $3==4 call cmixxior("jle")
 | |
| 
 | |
| proc cmxtxx
 | |
| with regorconst rm
 | |
| uses REG = {ANYCON,0}
 | |
|   gen cmp %2,%1
 | |
|       jxx[1] {label,1f}
 | |
|       inc %a
 | |
|       1:			    yields %a
 | |
| with rm regorconst
 | |
| uses REG = {ANYCON,0}
 | |
|   gen cmp %1,%2
 | |
|       jxx[2] {label,1f}
 | |
|       inc %a
 | |
|       1:			    yields %a
 | |
| 
 | |
| pat cmi tlt $1==4     call cmxtxx("jge","jle")
 | |
| pat cmi tle $1==4     call cmxtxx("jg","jl")
 | |
| pat cmi teq $1==4     call cmxtxx("jne","jne")
 | |
| pat cmi tne $1==4     call cmxtxx("je","je")
 | |
| pat cmi tge $1==4     call cmxtxx("jl","jg")
 | |
| pat cmi tgt $1==4     call cmxtxx("jle","jge")
 | |
| pat cmp tlt	      call cmxtxx("jae","jbe")
 | |
| pat cmp tle	      call cmxtxx("ja","jb")
 | |
| pat cmp teq	      call cmxtxx("jne","jne")
 | |
| pat cmp tne	      call cmxtxx("je","je")
 | |
| pat cmp tge	      call cmxtxx("jb","ja")
 | |
| pat cmp tgt	      call cmxtxx("jbe","jae")
 | |
| pat cms teq $1==4     call cmxtxx("jne","jne")
 | |
| pat cms tne $1==4     call cmxtxx("je","je")
 | |
| 
 | |
| proc cmxzxx example cmp zlt
 | |
| with regorconst rm STACK
 | |
|   gen cmp %2,%1
 | |
|       jxx[1] {label,$2}
 | |
| with rm regorconst STACK
 | |
|   gen cmp %1,%2
 | |
|       jxx[2] {label,$2}
 | |
| 
 | |
| pat cmp zlt	    call cmxzxx("jb","ja")
 | |
| pat cmp zle	    call cmxzxx("jbe","jae")
 | |
| pat cmp zeq	    call cmxzxx("je","je")
 | |
| pat cmp zne	    call cmxzxx("jne","jne")
 | |
| pat cmp zge	    call cmxzxx("jae","jbe")
 | |
| pat cmp zgt	    call cmxzxx("ja","jb")
 | |
| pat cms zeq $1==4   call cmxzxx("je","je")
 | |
| pat cms zne $1==4   call cmxzxx("jne","jne")
 | |
| 
 | |
| pat cms zne $1==8
 | |
| with regorconst regorconst rm rm STACK
 | |
|   gen cmp %3,%1
 | |
|       jne {label,$2}
 | |
|       cmp %4,%2
 | |
|       jne {label,$2}
 | |
| with rm rm regorconst regorconst STACK
 | |
| kills ALL
 | |
|   gen cmp %1,%3
 | |
|       jne {label,$2}
 | |
|       cmp %2,%4
 | |
|       jne {label,$2}
 | |
| 
 | |
| pat cms zeq $1==8
 | |
| with regorconst regorconst rm rm STACK
 | |
|   gen cmp %3,%1
 | |
|       jne {label, 1f}
 | |
|       cmp %4,%2
 | |
|       je {label,$2}
 | |
|       1:
 | |
| with rm rm regorconst regorconst STACK
 | |
| kills ALL
 | |
|   gen cmp %1,%3
 | |
|       jne {label,1f}
 | |
|       cmp %2,%4
 | |
|       je {label,$2}
 | |
|       1:
 | |
| 
 | |
| proc andzxx example and zeq
 | |
| with regorconst rm STACK
 | |
|   gen check %2,%1
 | |
|       jxx* {label,$2}
 | |
| with exact rm regorconst
 | |
|   kills ALL
 | |
|   gen check %1,%2
 | |
|       jxx* {label,$2}
 | |
| 
 | |
| pat and zeq $1==4 call andzxx("je")
 | |
| pat and zne $1==4 call andzxx("jne")
 | |
| 
 | |
| proc locandzxx example loc and zeq
 | |
| with rm1 STACK
 | |
|   gen testb %1,{ANYCON,$1}
 | |
|       jxx* {label,$3}
 | |
| with GENREG STACK
 | |
|   gen testb %1.1,{ANYCON,$1}
 | |
|       jxx* {label,$3}
 | |
| with exact RREG
 | |
|   kills ALL
 | |
|   gen check %1,{ANYCON,$1}
 | |
|       jxx* {label,$3}
 | |
| 
 | |
| pat loc and zeq $1<256 && $1>=0 && $2==4 call locandzxx("je")
 | |
| pat loc and zne $1<256 && $1>=0 && $2==4 call locandzxx("jne")
 | |
| 
 | |
| proc locbxx example loc beq
 | |
| with rm1 STACK
 | |
|   gen cmpb %1,{ANYCON,$1}
 | |
|       jxx* {label,$2}
 | |
| with rm STACK
 | |
|   gen cmp %1,{ANYCON,$1}
 | |
|       jxx* {label,$2}
 | |
| 
 | |
| pat loc beq $1<256 && $1>=0 call locbxx("je")
 | |
| pat loc bne $1<256 && $1>=0 call locbxx("jne")
 | |
| 
 | |
| proc loccmuzxx example loc cmu zeq
 | |
| with rm1 STACK
 | |
|   gen cmpb %1,{ANYCON,$1}
 | |
|       jxx* {label,$3}
 | |
| with rm STACK
 | |
|   gen cmp %1,{ANYCON,$1}
 | |
|       jxx* {label,$3}
 | |
| 
 | |
| pat loc cmu zeq $1<256 && $1>=0 && $2==4 call loccmuzxx("je")
 | |
| pat loc cmu zne $1<256 && $1>=0 && $2==4 call loccmuzxx("jne")
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 13 : Branch Instructions				   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat lab topeltsize($1)==4 && !fallthrough($1)
 | |
|   with STACK
 | |
|   kills ALL
 | |
|   gen labeldef $1                 yields eax
 | |
| 
 | |
| pat lab topeltsize($1)==4 && fallthrough($1)
 | |
|   with ACC STACK
 | |
|   kills ALL
 | |
|   gen labeldef $1                 yields eax
 | |
| 
 | |
| pat lab topeltsize($1)!=4
 | |
|   with STACK
 | |
|   kills ALL
 | |
|   gen labeldef $1
 | |
| 
 | |
| pat bra topeltsize($1)==4
 | |
|   with ACC STACK
 | |
|   gen jmp {label,$1}
 | |
| 
 | |
| pat bra topeltsize($1)!=4
 | |
|   with STACK
 | |
|   gen jmp {label,$1}
 | |
| 
 | |
| proc bxx example blt
 | |
| with regorconst rm STACK
 | |
|   gen cmp %2,%1
 | |
|       jxx[1] {label,$1}
 | |
| with rm regorconst STACK
 | |
|   gen cmp %1,%2
 | |
|       jxx[2] {label,$1}
 | |
| 
 | |
| pat blt		call bxx("jl","jg")
 | |
| pat ble		call bxx("jle","jge")
 | |
| pat beq		call bxx("je","je")
 | |
| pat bne		call bxx("jne","jne")
 | |
| pat bge		call bxx("jge","jle")
 | |
| pat bgt		call bxx("jg","jl")
 | |
| 
 | |
| proc zxx example zlt
 | |
| with rm STACK
 | |
|   gen test %1
 | |
|       jxx* {label,$1}
 | |
| 
 | |
| pat zlt		call zxx("js")
 | |
| pat zge		call zxx("jns")
 | |
| 
 | |
| /* Explicit test for ZLE and ZGT. We must make sure that the OC
 | |
|    flag is cleared.
 | |
| */
 | |
| pat zle
 | |
| with rm STACK
 | |
|   gen 
 | |
|       killcc.
 | |
|       test %1
 | |
|       jle {label,$1}
 | |
| 
 | |
| pat zgt
 | |
| with rm STACK
 | |
|   gen
 | |
|       killcc.
 | |
|       test %1
 | |
|       jg {label, $1}
 | |
| 
 | |
| pat zne
 | |
| with rm+rm1 STACK
 | |
|   gen test %1
 | |
|       jne {label,$1}
 | |
| 
 | |
| pat zeq
 | |
| with rm+rm1 STACK
 | |
|   gen test %1
 | |
|       je {label,$1}
 | |
| 
 | |
| /*******************************************************************
 | |
|  *  Group 14 : Procedure-call Instructions			   *
 | |
|  *******************************************************************/
 | |
| 
 | |
| pat cal
 | |
|   kills ALL
 | |
|   gen proccall {label,$1}
 | |
| 
 | |
| pat cai
 | |
|   with rm
 | |
|   kills ALL
 | |
|   gen proccall %1
 | |
| 
 | |
| #ifdef REGVARS
 | |
| pat lfr adi stl $1==4 && $2==4 && inreg($3) > 0
 | |
|   kills ALL
 | |
|   gen pop {LOCAL,$3,4}
 | |
|       add {LOCAL,$3,4}, eax
 | |
| #endif
 | |
| 
 | |
| pat lfr $1==4			yields eax
 | |
| 
 | |
| pat lfr $1==8			yields edx eax
 | |
| 
 | |
| pat ret $1==0
 | |
|   kills ALL
 | |
|   gen
 | |
| #ifdef REGVARS
 | |
| 	return
 | |
| #else
 | |
|       leave.
 | |
|       ret.
 | |
| #endif
 | |
| 
 | |
| pat ret $1==4
 | |
|   with ACC
 | |
|   kills ALL
 | |
|   gen
 | |
| #ifdef REGVARS
 | |
| 	return
 | |
| #else
 | |
|       leave.
 | |
|       ret.
 | |
| #endif
 | |
| 
 | |
| pat ret $1==8
 | |
|   with ACC DXREG
 | |
|   kills ALL
 | |
|   gen
 | |
| #ifdef REGVARS
 | |
| 	return
 | |
| #else
 | |
|       leave.
 | |
|       ret.
 | |
| #endif
 | |
| 
 | |
| /********************************************************************
 | |
|  *  Group 15 : Miscellaneous Instructions			    *
 | |
|  ********************************************************************/
 | |
| 
 | |
| pat asp $1==4
 | |
| with exact a_word
 | |
| with STACK
 | |
|   uses CXREG /* GENREG may contain lfr area */
 | |
|   gen pop %a
 | |
| 
 | |
| pat asp $1==8
 | |
| with exact a_word a_word
 | |
| with STACK
 | |
|   uses CXREG /* GENREG may contain lfr area */
 | |
|   gen pop %a
 | |
|       pop %a
 | |
| 
 | |
| pat asp $1==0-4
 | |
| with STACK					yields ebp
 | |
| 
 | |
| pat asp
 | |
| with STACK
 | |
|   gen add esp,{ANYCON,$1}
 | |
| 
 | |
| pat ass $1==4
 | |
| with rmorconst STACK
 | |
|   gen add esp,%1
 | |
| 
 | |
| pat ass !defined($1)
 | |
| with rm rmorconst STACK
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       add esp,%2
 | |
| 
 | |
| pat blm $1==0					leaving asp 4
 | |
| 
 | |
| pat blm $1>0
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1/4}
 | |
|       proccall {label, ".blm"}
 | |
| 
 | |
| pat bls $1==4
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen sar ecx,{ANYCON,2}
 | |
|       proccall {label, ".blm"}
 | |
| 
 | |
| pat bls !defined($1)
 | |
| with rm-CXREG CXREG
 | |
| kills ALL
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       sar ecx,{ANYCON,2}
 | |
|       proccall {label, ".blm"}
 | |
| 
 | |
| pat csa $1==4
 | |
| with BXREG ACC
 | |
| kills ALL
 | |
|   gen jmp {label, ".csa4"}
 | |
| 
 | |
| pat csa !defined($1)
 | |
| with rm-BXREG-ACC BXREG ACC
 | |
| kills ALL
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       jmp {label, ".csa4"}
 | |
| 
 | |
| pat csb $1==4
 | |
| with BXREG ACC
 | |
| kills ALL
 | |
|   gen jmp {label, ".csb4"}
 | |
| 
 | |
| pat csb !defined($1)
 | |
| with rm-BXREG-ACC BXREG ACC
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       jmp {label, ".csb4"}
 | |
| 
 | |
| pat dup $1==4
 | |
| with anyreg				yields %1 %1
 | |
| with ACC1				yields %1 %1
 | |
| 
 | |
| pat dup $1==8
 | |
| with regorconst regorconst		yields %2 %1 %2 %1
 | |
| 
 | |
| pat dup
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".dup"}
 | |
| 
 | |
| pat dus $1==4
 | |
| with CXREG
 | |
| kills ALL
 | |
|   gen proccall {label, ".dup"}
 | |
| 
 | |
| pat dus !defined($1)
 | |
| with rm-CXREG CXREG
 | |
| kills ALL
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       proccall {label, ".dup"}
 | |
| 
 | |
| pat exg $1==4
 | |
| with a_word a_word			yields %1 %2
 | |
| 
 | |
| pat exg $1==8
 | |
| with a_word a_word a_word a_word	yields %2 %1 %4 %3
 | |
| 
 | |
| pat exg defined($1)
 | |
| kills ALL
 | |
|   gen mov ecx,{ANYCON,$1}
 | |
|       proccall {label, ".exg"}
 | |
| 
 | |
| pat exg
 | |
| with CXREG
 | |
|   kills ALL
 | |
|   gen proccall {label, ".exg"}
 | |
| 
 | |
| pat gto
 | |
| kills ALL
 | |
|   gen mov ebx,{ADDR_EXTERN,$1}
 | |
|       jmp {label, ".gto"}
 | |
| 
 | |
| pat fil
 | |
|   gen mov {EXTERN,"hol0+4"},{ADDR_EXTERN,$1}
 | |
| 
 | |
| pat lim
 | |
|   uses REG
 | |
|   gen mov %a,{EXTERN,".ignmask"}	yields %a
 | |
| 
 | |
| pat lin
 | |
|   gen mov {EXTERN,"hol0"},{ANYCON,$1}
 | |
| 
 | |
| pat lni
 | |
|   gen inc {EXTERN,"hol0"}
 | |
| 
 | |
| pat lor $1==0				yields ebp
 | |
| 
 | |
| pat lor $1==1
 | |
| with STACK
 | |
|   uses REG
 | |
|   gen mov %a,esp			yields %a
 | |
| 
 | |
| pat lor $1==2
 | |
|   uses REG
 | |
|   gen mov %a,{EXTERN,".reghp"}		yields %a
 | |
| 
 | |
| pat mon
 | |
| with ACC
 | |
| kills ALL
 | |
|   gen proccall {label, ".mon"}
 | |
| 
 | |
| pat nop
 | |
| kills ALL
 | |
| #ifdef DEBUG
 | |
|   gen proccall {label, ".nop"}
 | |
| #endif
 | |
| 
 | |
| pat rck $1==4
 | |
| with BXREG ACC
 | |
| kills ALL
 | |
|   gen proccall {label, ".rck"}		yields eax
 | |
| 
 | |
| pat rck !defined($1)
 | |
| with rm-BXREG-ACC BXREG ACC
 | |
| kills ALL
 | |
|   gen cmp %1,{ANYCON,4}
 | |
|       jne {label, ".unknown"}
 | |
|       proccall {label, ".rck"}		yields eax
 | |
| 
 | |
| pat rtt						leaving ret 0
 | |
| 
 | |
| pat sig
 | |
| with REG
 | |
|   gen xchg {EXTERN,".trppc"},%1		yields %1
 | |
| 
 | |
| pat sim
 | |
| with regorconst
 | |
|   gen mov {EXTERN,".ignmask"},%1
 | |
| 
 | |
| pat str $1==0
 | |
| with rmorconst
 | |
|   gen mov ebp,%1
 | |
| 
 | |
| pat str $1==1
 | |
| with rmorconst STACK
 | |
|   gen mov esp,%1
 | |
| 
 | |
| pat str $1==2
 | |
| kills ALL
 | |
|   gen proccall {label, ".strhp"}
 | |
| 
 | |
| pat trp
 | |
| with ACC
 | |
| kills ALL
 | |
|   gen proccall {label, ".Xtrp"}
 |