ack/mach/i386/ncg/table
George Koehler f0a2c84d93 Tweak i386 rules for adi 8, sli 8, sru 8.
Add EXACT to the rule for adi 8, in the same way that the old rules
for and 8, ior 8, xor 8 have EXACT.

Add rules for sli 8 and sru 8 when shifting 32 bits, and add
assertions in llshift_e.c to test these rules.
2019-09-18 14:09:51 -04:00

3211 lines
83 KiB
Plaintext

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