2942 lines
		
	
	
	
		
			77 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			2942 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 = "$Header$"
 | 
						|
 | 
						|
/*
 | 
						|
 * 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).
 | 
						|
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.
 | 
						|
ORB "orb" REG1:ro, REG1:ro:cc.		/* use ORB for tests */
 | 
						|
ORW "o16 or" REG2:ro, REG2:ro:cc.	/* use ORW for tests */
 | 
						|
OR "or" anyreg:ro, anyreg:ro:cc.	/* Use OR for tests */
 | 
						|
#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:cc, ANYCON+SHIFT_CREG:ro cost(2,10).
 | 
						|
rcr rm:rw:cc, ANYCON+SHIFT_CREG:ro cost(2,10).
 | 
						|
ret cost(1,10).
 | 
						|
rol rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
ror rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
sal rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
sar rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
sbb rm:rw:cc, regorconst:ro.
 | 
						|
sbb anyreg:rw:cc, rmorconst:ro.
 | 
						|
shl rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
shr rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
sxx rm:rw:cc, ANYCON+SHIFT_CREG:ro.
 | 
						|
#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, regorconst:ro kills :cc.
 | 
						|
testb "testb" REG1:ro, rmorconst:ro kills :cc.
 | 
						|
testw "o16 test" rm2:ro, regorconst:ro kills :cc.
 | 
						|
testw "o16 test" REG2: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).
 | 
						|
 | 
						|
 | 
						|
/*****************************************************************/
 | 
						|
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 OR %1,%1
 | 
						|
 | 
						|
to test memory
 | 
						|
gen cmp %1, {ANYCON,0}
 | 
						|
 | 
						|
to test REG1
 | 
						|
gen ORB %1,%1
 | 
						|
 | 
						|
to test memory1
 | 
						|
gen cmpb %1, {ANYCON,0}
 | 
						|
 | 
						|
to test REG2
 | 
						|
gen ORW %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
 | 
						|
 | 
						|
pat lol lol $1==$2
 | 
						|
#ifdef REGVARS
 | 
						|
	    && inreg($1) <= 0
 | 
						|
#endif
 | 
						|
						leaving lol $1 dup 4
 | 
						|
 | 
						|
#ifdef REGVARS
 | 
						|
pat lol lol stl $1==$2 && 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
 | 
						|
 | 
						|
pat loe loe $1==$2				leaving loe $1 dup 4
 | 
						|
 | 
						|
#ifdef REGVARS
 | 
						|
pat loe loe stl $1==$2 && 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 lil $1==$2				leaving lil $1 dup 4
 | 
						|
 | 
						|
pat lil lil stl $1==$2				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}
 | 
						|
  with halfindir regorconst
 | 
						|
  kills all_mems
 | 
						|
  gen mov %1,%2			yields %1	leaving stf $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 lol adp stl loi stl $1==$2 && $2==$4 && $5<=4
 | 
						|
					leaving lol $1 loi $5 stl $6 lol $2 adp $3 stl $4
 | 
						|
 | 
						|
#ifdef REGVARS
 | 
						|
pat lol lol adp stl loi loc loc cii $1==$2 && $2==$4 && $5==1 && inreg($1) > 0 && $6==1 && $7==4
 | 
						|
uses REG
 | 
						|
gen movsxb %a,{indir_r1, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lol $2 adp $3 stl $4
 | 
						|
 | 
						|
pat lol lol adp stl loi $1==$2 && $2==$4 && $5==1 && inreg($1) > 0
 | 
						|
uses REG1 = {indir_r1, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lol $2 adp $3 stl $4
 | 
						|
 | 
						|
pat lol lol adp stl loi loc loc cii $1==$2 && $2==$4 && $5==2 && inreg($1) > 0 && $6==2 && $7==4
 | 
						|
uses REG
 | 
						|
gen movsx %a,{indir_r2, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lol $2 adp $3 stl $4
 | 
						|
 | 
						|
pat lol lol adp stl loi $1==$2 && $2==$4 && $5==2 && inreg($1) > 0
 | 
						|
uses REG2 = {indir_r2, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lol $2 adp $3 stl $4
 | 
						|
 | 
						|
pat lol lol adp stl loi $1==$2 && $2==$4 && $5==4 && inreg($1) > 0
 | 
						|
uses REG = {indir_r, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lol $2 adp $3 stl $4
 | 
						|
pat adp stl inreg($2) > 0		leaving stl $2 lol $2 adp $1 stl $2
 | 
						|
#endif
 | 
						|
 | 
						|
pat lol lol adp stl $1==$2 && $2==$4
 | 
						|
uses ADDREG={LOCAL,$1,4}	yields %a
 | 
						|
					leaving lol $2 adp $3 stl $2
 | 
						|
 | 
						|
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 lil adp sil $1==$2 && $1==$4 && inreg($1)==reg_any
 | 
						|
uses ADDREG={indir_r, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lil $1 adp $3 sil $4
 | 
						|
 | 
						|
pat lil lil inc sil $1==$2 && $1==$4 && inreg($1)==reg_any
 | 
						|
uses REG={indir_r, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lil $1 inc sil $4
 | 
						|
 | 
						|
pat lil lil dec sil $1==$2 && $1==$4 && inreg($1)==reg_any
 | 
						|
uses REG={indir_r, regvar($1)}
 | 
						|
				yields %a
 | 
						|
					leaving lil $1 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 loe adp ste $1==$2 && $1==$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 REG = {ANYCON,0}
 | 
						|
  gen test %1
 | 
						|
      jxx* {label,1f}
 | 
						|
      inc %a
 | 
						|
      1:			    yields %a
 | 
						|
 | 
						|
pat tlt call txx("jge")
 | 
						|
pat tle call txx("jg")
 | 
						|
pat teq call txx("jne")
 | 
						|
pat tne call txx("je")
 | 
						|
pat tge call txx("jl")
 | 
						|
pat tgt call txx("jle")
 | 
						|
 | 
						|
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("jl")
 | 
						|
pat zle		call zxx("jle")
 | 
						|
pat zge		call zxx("jge")
 | 
						|
pat zgt		call zxx("jg")
 | 
						|
 | 
						|
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"}
 |