From 4da1930ff4ee95c6970057efb148fc3d2bafaf09 Mon Sep 17 00:00:00 2001 From: ceriel Date: Wed, 15 Feb 1989 16:39:58 +0000 Subject: [PATCH] Initial revision --- mach/i386/ncg/table | 2603 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2603 insertions(+) create mode 100644 mach/i386/ncg/table diff --git a/mach/i386/ncg/table b/mach/i386/ncg/table new file mode 100644 index 000000000..4cfd7bb2e --- /dev/null +++ b/mach/i386/ncg/table @@ -0,0 +1,2603 @@ +/* + * (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. +cbw "o16 cbw" kills ah cost(2,3). +cdq kills edx cost(1,3). +cwde 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. +leave cost(1,4). +loop label kills ecx. +#ifdef REGVARS +mov LOCAL:wo, memory: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). +mul rmorconst:ro kills :cc eax edx cost(2,41). +neg rmorconst:rw:cc. +not rmorconst:rw:cc. +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 memory 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 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 GENREG + gen move {ANYCON,0},%a + move %1,%a.1 + push %a + +from rm1 to STACK + gen push eax + xor eax,eax + movb al,%1 + xchg {indir_r,esp},eax + +from rm2 to STACK + gen push eax + xor eax,eax + movw ax,%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={ANYCON,0} + gen + move %1,%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 4 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,4} + 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,4} + 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 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 exact ADDR_LOCAL leaving stl %1.ind+$1 + 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 exact ADDR_LOCAL leaving stl %1.ind + with exact ADDR_EXTERN leaving ste %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 + with addreg regorconst regorconst + kills all_mems + gen move %2,{indir_r,%1} + move %3,{indir_r_off,%1,4} + with exact addreg STACK + kills all_mems + gen pop {indir_r,%1} + pop {indir_r_off,%1,4} + with reg_off regorconst regorconst + kills all_mems + gen move %2,{indir_r_off,%1.reg,%1.off} + move %3,{indir_r_off,%1.reg,%1.off+4} + with exact reg_off STACK + kills all_mems + gen pop {indir_r_off,%1.reg,%1.off} + pop {indir_r_off,%1.reg,%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} + move %3,{indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4} + with exact indexed_r_off STACK + kills all_mems + gen pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off} + pop {indir_indexed_r_off,%1.reg,%1.reg2,%1.scale,%1.off+4} + with indexed_off regorconst regorconst + kills all_mems + gen move %2,{indir_indexed_off,%1.reg,%1.scale,%1.off} + move %3,{indir_indexed_off,%1.reg,%1.scale,%1.off+4} + with exact indexed_off STACK + kills all_mems + gen pop {indir_indexed_off,%1.reg,%1.scale,%1.off} + pop {indir_indexed_off,%1.reg,%1.scale,%1.off+4} + with exact ADDR_EXTERN leaving sde %1.off + with exact ADDR_LOCAL leaving sdl %1.ind + +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} + +/* Funny things happen when the sign changes in the stl parameters */ + + with exact ADDR_LOCAL leaving stl %1.ind+$1 + stl %1.ind+$1+4 + with exact ADDR_EXTERN leaving sde %1.off+$1 + 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 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 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 cal ".fif4" +pat fif $1==8 leaving cal ".fif8" +pat fef $1==4 leaving dup 4 cal ".fef4" +pat fef $1==8 +with REG REG + kills ALL + gen push %1 + push %2 + push %1 leaving 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 + +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") +#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") +#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") + +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 dec lol stf $1==$4 && $2==$5 && inreg($1)==reg_any + 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") +#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") + +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") + +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") + +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") + +#ifdef REGVARS +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("sub") +pat lol loc adi stl $1==$4 && $3==4 call lolcxxstl("sub") +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 +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 $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 $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 + +pat lol lof adp lol stf $1==$4 && $2==$5 && $3==1 + leaving lol $1 lof $2 inc lol $4 stf $5 +pat lol lof adp lol stf $1==$4 && $2==$5 && $3==(0-1) + leaving lol $1 lof $2 dec lol $4 stf $5 + +#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 +#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 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 && $3==1 + leaving loe $1 lof $2 inc loe $1 stf $2 + +pat loe lof adp loe stf $1==$4 && $2==$5 && $3==0-1 + leaving loe $1 lof $2 dec loe $1 stf $2 + +pat loe lof adp loe stf $1==$4 && $2==$5 + leaving loc $3 loe $1 lof $2 adi 4 loe $1 stf $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 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 cbw. + cwde. yields eax +with exact rmorconst1 +uses reusing %1, ACC1=%1 +gen cbw. + cwde. yields eax + +pat loc loc cii $1==2 && $2==4 +with ACC +gen cwde. yields eax +with exact rmorconst2 +uses ACC +gen movw ax,%1 + cwde. yields eax + +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 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) +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 bra + 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 BXREG /* GENREG may contain lfr area */ + gen pop %a + +pat asp $1==8 +with exact a_word a_word +with STACK + uses BXREG /* 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 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 + gen proccall {label, ".nop"} + +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"} -- 2.34.1