--- /dev/null
+/*
+ * (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"}