/************************************************************/ /************************************************************/ /******* ******/ /******* 8 0 8 0 B A C K E N D T A B L E ******/ /******* ******/ /************************************************************/ /************************************************************/ rcsid = "$Id$" EM_WSIZE = 2 EM_PSIZE = 2 EM_BSIZE = 4 SL=4 PROPERTIES areg /* the a-register */ lbreg /* the registers used as localbase */ reg /* the free registers */ regpair /* register pairs bc, de and hl */ regind /* register indirect */ dereg /* de-register-pair */ hlreg /* hl-register-pair */ hl_or_de /* de- or hl-register-pair */ localbase stackpointer psword REGISTERS a :areg,reg. b,c :lbreg. d,e,h,l :reg. lb("b")=b+c :regpair, localbase, regind. de("d")=d+e :regpair, regind, dereg, hl_or_de. hl("h")=h+l :regpair, hlreg, hl_or_de. sp :stackpointer. psw=a :psword. /* in fact psw also includes condition codes */ TOKENS const1 = { INT num; } 1 num. const2 = { INT num; } 2 num. label = { ADDR off; } 2 off. m = { } 2 cost(0,3) "m". SETS reg1 = reg + lbreg + m. b_d_h_sp = regpair + stackpointer. b_d_h_psw = regpair + psword. immediate = const2 + label. src1 = reg. src2 = hl_or_de + const2 + label. src1or2 = src1 + src2. INSTRUCTIONS /* aci const1:ro kills a:cc cost(2, 7). */ adc reg1:ro kills a:cc cost(1, 4). add reg1:ro kills a:cc cost(1, 4). /* adi const1:ro kills a:cc cost(2, 7). */ ana reg1:ro kills a:cc cost(1, 4). ani const1:ro kills a:cc cost(2, 7). Call "call" label:ro cost(3,17). /* 'call' is a reserved word */ /* cc label:ro cost(3,14). */ /* cm label:ro cost(3,14). */ cma kills a cost(3,14). cmc kills:cc cost(1, 4). cmp reg1:ro kills:cc cost(1, 4). /* cnc label:ro cost(3,14). */ cnz label:ro cost(3,14). /* cp label:ro cost(3,14). */ /* cpe label:ro cost(3,14). */ cpi const1:ro kills:cc cost(2, 7). /* cpo label:ro cost(3,14). */ /* cz label:ro cost(3,14). */ /* daa kills a:cc cost(1, 4). */ dad b_d_h_sp:ro kills hl:cc cost(1,10). dcr reg+lbreg:rw:cc cost(1, 5). dcr m:rw:cc cost(1, 7). dcx b_d_h_sp:rw cost(1, 5). /* di cost(1, 4). */ /* ei cost(1, 4). */ /* hlt cost(1, 4). */ /* in const1:ro cost(2,10). */ inr reg+lbreg:rw:cc cost(1, 5). inr m:rw:cc cost(1, 7). inx b_d_h_sp:rw cost(1, 5). jc label:ro cost(3,10). jm label:ro cost(3,10). jmp label:ro cost(3,10). jnc label:ro cost(3,10). jnz label:ro cost(3,10). jp label:ro cost(3,10). /* jpe label:ro cost(3,10). */ /* jpo label:ro cost(3,10). */ jz label:ro cost(3,10). lda label:ro kills a cost(3,13). ldax regind:ro kills a cost(1, 7). lhld label:ro kills hl cost(3,16). lxi b_d_h_sp:wo,immediate:ro cost(3,10). mov reg+lbreg:wo,reg+lbreg:ro cost(1, 5). mov m:wo,reg1:ro cost(1, 4). mov reg1:wo,m:ro cost(1, 4). mvi reg1:wo,const1:ro cost(2, 7). /* nop cost(1, 3). */ ora reg1:ro kills a:cc cost(1, 4). /* ori const1:ro kills a:cc cost(2, 7). */ /* out const1:ro cost(2,10). */ pchl cost(1, 5). pop b_d_h_psw:wo cost(1,10). push b_d_h_psw:ro cost(1,10). ral kills a:cc cost(1, 4). rar kills a:cc cost(1, 4). /* rc cost(1, 8). */ ret cost(1,10). rlc kills a:cc cost(1, 4). /* rm cost(1, 8). */ /* rnc cost(1, 8). */ /* rnz cost(1, 8). */ /* rp cost(1, 8). */ /* rpe cost(1, 8). */ /* rpo cost(1, 8). */ rrc kills a:cc cost(1, 4). /* rst const1:ro cost(1,11). */ /* rz cost(1, 8). */ sbb reg1:ro kills a:cc cost(1, 4). /* sbi const1:ro kills a:cc cost(2, 7). */ shld label:ro cost(3,16). sphl cost(1, 5). sta label:ro cost(3,13). stax regind:ro cost(1, 7). /* stc kills:cc cost(1, 4). */ sub reg1:ro kills a:cc cost(1, 4). sui const1:ro kills a:cc cost(2, 7). xchg kills de hl cost(1, 4). xra reg1:ro kills a:cc cost(1, 4). /* xri const1:ro kills a:cc cost(2, 7). */ xthl kills hl cost(1,18). MOVES from reg to reg gen mov %2,%1 from const1 %num==0 to areg gen xra a from const1 to reg gen mvi %2,%1 from immediate to b_d_h_sp gen lxi %2,%1 from reg to regpair gen mov %2.2,%1 mvi %2.1,{const1,0} from regpair to regpair gen mov %2.1,%1.1 mov %2.2,%1.2 TESTS to test areg /* dummy test, never used */ gen ora a STACKINGRULES from regpair to STACK gen push %1 from immediate + reg to STACK uses hl_or_de gen move %1,%a push %a from immediate + reg to STACK gen push hl move %1,hl xthl. COERCIONS from STACK uses regpair gen pop %a yields %a from STACK uses hl_or_de gen pop %a yields %a.2 from STACK uses areg gen dcx sp pop psw inx sp yields a from immediate uses regpair gen move %1,%a yields %a from hl_or_de uses hl_or_de gen xchg. yields %a from regpair uses regpair gen move %1,%a yields %a from reg uses reusing %1, hl_or_de gen move %1,%a.2 move {const1,0},%a.1 yields %a from hl_or_de yields %1.2 from const2 uses hl_or_de gen move %1,%a yields %a.2 from hl_or_de uses areg gen move %1.2,a yields a PATTERNS /*********************************************/ /* Group 1: Load instructions */ /*********************************************/ pat loc yields {const2,$1} pat ldc yields {const2,highw($1)} {const2,loww($1)} pat lol uses hlreg={const2,$1}, dereg gen dad lb mov e,{m} inx hl mov d,{m} yields de pat loe uses hlreg gen lhld {label,$1} yields hl pat lil uses hlreg={const2,$1}, dereg gen dad lb mov e,{m} inx hl mov h,{m} mov l,e mov e,{m} inx hl mov d,{m} yields de pat lof with hl_or_de kills hl_or_de uses hl_or_de={const2,$1} gen dad de mov e,{m} inx hl mov d,{m} yields de pat lal uses hlreg={const2,$1} gen dad lb yields hl pat lae yields {label,$1} pat lxl $1==0 yields lb pat lxl $1==1 uses dereg, hlreg gen move {const2,SL},hl dad lb mov e,{m} inx hl mov d,{m} yields de pat lxl $1>1 && $1<256 uses dereg, areg={const1,$1}, hlreg gen move lb,de 1: lxi hl,{const2,SL} dad de mov e,{m} inx hl mov d,{m} dcr a jnz {label,1b} yields de pat lxa $1==0 uses hlreg gen move {const2,SL},hl dad lb yields hl pat lxa $1==1 uses dereg, hlreg gen move {const2,SL},hl dad lb mov e,{m} inx hl mov d,{m} lxi hl,{const2,SL} dad de yields hl pat lxa $1>1 && $1<256 uses dereg, hlreg, areg={const1,$1} gen move lb,de 1: lxi hl,{const2,SL} dad de mov e,{m} inx hl mov d,{m} dcr a jnz {label,1b} lxi hl,{const2,SL} dad de yields hl pat loi $1==1 with exact label uses areg gen lda %1 yields a with dereg uses areg gen ldax de yields a with hlreg uses reusing %1, reg gen mov %a,{m} yields %a pat loi $1==2 with exact label gen lhld %1 yields hl with hlreg uses dereg gen mov e,{m} inx %1 mov d,{m} yields de pat loi $1==4 with exact label gen lhld %1 xchg. lhld {label,%1.off+2} yields hl de with exact label gen lhld {label,%1.off+2} xchg. lhld %1 yields de hl with hlreg uses dereg, areg gen mov e,{m} inx %1 mov d,{m} inx hl mov a,{m} inx hl mov h,{m} mov l,a yields hl de pat loi $1<=510 with hl_or_de STACK uses hl_or_de={const2,$1-1}, areg gen dad de mvi a,{const1,$1/2} 1: mov d,{m} dcx hl mov e,{m} dcx hl push de dcr a jnz {label,1b} pat loi $1>=512 kills ALL /* 'uses dereg={const2,$1}' fails to kill de. */ gen lxi de,{const2,$1} Call {label,".loi"} pat los $1==2 with dereg kills ALL gen Call {label,".loi"} pat ldl with STACK uses dereg, hlreg={const2,$1+3} gen dad lb mov d,{m} dcx hl mov e,{m} dcx hl push de mov d,{m} dcx hl mov e,{m} yields de pat lde with STACK gen lhld {label,$1+2} push hl lhld {label,$1} yields hl with uses dereg, hlreg gen lhld {label,$1} xchg. lhld {label,$1+2} yields hl de with uses dereg, hlreg gen lhld {label,$1+2} xchg. lhld {label,$1} yields de hl pat ldf with hl_or_de STACK uses hl_or_de={const2,$1+3} gen dad de mov d,{m} dcx hl mov e,{m} dcx hl push de mov d,{m} dcx hl mov e,{m} yields de pat lpi uses hl_or_de={label,$1} yields %a /******************************************/ /* Group 2: Store instructions */ /******************************************/ pat stl lol $1==$2 with dereg yields de de leaving stl $1 pat stl with dereg uses hlreg={const2,$1} gen dad lb mov {m},e inx hl mov {m},d pat ste loe $1==$2 with hlreg yields hl hl leaving ste $1 pat ste with hlreg gen shld {label,$1} pat sil with dereg uses hlreg={const2,$1}, areg gen dad lb mov a,{m} inx hl mov h,{m} mov l,a mov {m},e inx hl mov {m},d pat sil lil $1==$2 with dereg uses hlreg={const2,$1}, areg gen dad lb mov a,{m} inx hl mov h,{m} mov l,a mov {m},e inx hl mov {m},d yields de pat lil loc adi sil $1==$4 && $3==2 uses hlreg={const2,$1}, dereg, areg gen dad lb mov e,{m} inx hl mov h,{m} mov l,e mov e,{m} inx hl mov d,{m} push hl lxi hl,{const2,$2} dad de xchg. pop hl mov {m},d dcx hl mov {m},e pat lil inc sil $1==$3 uses hlreg={const2,$1}, areg gen dad lb mov a,{m} inx hl mov h,{m} mov l,a inr {m} jnz {label,1f} inx hl inr {m} 1: pat lil dec sil $1==$3 uses hlreg={const2,$1}, dereg gen dad lb mov e,{m} inx hl mov h,{m} mov l,e mov e,{m} inx hl mov d,{m} dcx de mov {m},d dcx hl mov {m},e pat stf with hl_or_de STACK uses hl_or_de={const2,$1} gen dad de pop de mov {m},e inx hl mov {m},d pat sti $1==1 with label areg gen sta %1 with dereg areg gen stax de with hlreg reg gen mov {m},%2 pat sti $1==2 with label hlreg gen shld %1 with hlreg dereg gen mov {m},e inx %1 mov {m},d with dereg hlreg gen xchg. mov {m},e inx %2 mov {m},d pat sti $1==4 with label hlreg dereg gen shld %1 xchg. shld {label,%1.off+2} with label dereg hlreg gen shld {label,%1.off+2} xchg. shld %1 with hlreg dereg kills ALL gen mov {m},e inx hl mov {m},d inx hl pop de mov {m},e inx hl mov {m},d pat sti $1<512 with hlreg kills ALL uses areg={const1,$1/2}, dereg gen 1: pop de mov {m},e inx hl mov {m},d inx hl dcr a jnz {label,1b} pat sti kills ALL gen lxi de,{const2,$1} Call {label,".sti"} pat sts $1==2 with dereg kills ALL gen Call {label,".sti"} pat sdl with dereg kills ALL uses hlreg={const2,$1} gen dad lb mov {m},e inx hl mov {m},d inx hl pop de mov {m},e inx hl mov {m},d pat sde with hlreg kills ALL gen shld {label,$1} pop hl shld {label,$1+2} with hlreg dereg kills ALL gen shld {label,$1} xchg. shld {label,$1+2} with dereg hlreg kills ALL gen shld {label,$1+2} xchg. shld {label,$1} pat sdf with hl_or_de kills ALL uses hl_or_de={const2,$1} gen dad de pop de mov {m},e inx hl mov {m},d inx hl pop de mov {m},e inx hl mov {m},d /****************************************/ /* Group 3: Integer arithmetic */ /****************************************/ pat adi $1==2 with hlreg dereg gen dad de yields hl with dereg hlreg gen dad de yields hl with hlreg hlreg gen dad hl yields hl with dereg dereg gen xchg. dad hl yields hl pat adi $1==4 kills ALL gen Call {label,".adi4"} pat sbi $1==2 with hl_or_de hl_or_de uses areg gen mov a,%2.2 sub %1.2 mov %1.2,a mov a,%2.1 sbb %1.1 mov %1.1,a yields %1 with hl_or_de hl_or_de uses areg gen mov a,%2.2 sub %1.2 mov %2.2,a mov a,%2.1 sbb %1.1 mov %2.1,a yields %2 pat sbi $1==4 kills ALL gen Call {label,".sbi4"} pat mli $1==2 kills ALL gen Call {label,".mli2"} yields de pat mli $1==4 kills ALL gen Call {label,".mli4"} pat dvi $1==2 kills ALL /* 'uses areg={const1,129}' fails to kill a. */ gen mvi a,{const1,129} Call {label,".dvi2"} yields de pat dvi $1==4 kills ALL gen mvi a,{const1,129} Call {label,".dvi4"} pat rmi $1==2 kills ALL gen mvi a,{const1,128} Call {label,".dvi2"} yields de pat rmi $1==4 kills ALL gen mvi a,{const1,128} Call {label,".dvi4"} pat ngi $1==2 with hl_or_de uses areg gen xra a sub %1.2 mov %1.2,a mvi a,{const1,0} sbb %1.1 mov %1.1,a yields %1 pat ngi $1==4 kills ALL gen Call {label,".ngi4"} pat loc sli ($1 == 8) && ($2 == 2) with hl_or_de gen move %1.2, %1.1 mvi %1.2, {const1,0} yields %1 pat sli $1==2 kills ALL gen Call {label,".sli2"} yields de pat sli $1==4 kills ALL gen Call {label,".sli4"} pat sri $1==2 kills ALL gen mvi a,{const1,1} Call {label,".sri2"} yields de pat sri $1==4 kills ALL gen mvi a,{const1,1} Call {label,".sri4"} /********************************************/ /* Group 4: Unsigned arithmetic */ /********************************************/ pat adu leaving adi $1 pat sbu leaving sbi $1 pat mlu $1==2 kills ALL gen Call {label,".mlu2"} yields de pat mlu $1==4 kills ALL gen Call {label,".mli4"} pat dvu $1==2 kills ALL gen mvi a,{const1,1} Call {label,".dvi2"} yields de pat dvu $1==4 kills ALL gen mvi a,{const1,1} Call {label,".dvi4"} pat rmu $1==2 kills ALL gen mvi a,{const1,0} Call {label,".dvi2"} yields de pat rmu $1==4 kills ALL gen mvi a,{const1,0} Call {label,".dvi4"} pat slu leaving sli $1 pat loc sru ($1 == 8) && ($2 == 2) with hl_or_de gen move %1.1, %1.2 mvi %1.1, {const1,0} yields %1 pat sru $1==2 kills ALL gen mvi a,{const1,0} Call {label,".sri2"} yields de pat sru $1==4 kills ALL gen mvi a,{const1,0} Call {label,".sri4"} /********************************************/ /* Group 5: Floating point arithmetic */ /********************************************/ pat adf $1==4 leaving cal ".adf4" asp 4 pat adf $1==8 leaving cal ".adf8" asp 8 pat sbf $1==4 leaving cal ".sbf4" asp 4 pat sbf $1==8 leaving cal ".sbf8" asp 8 pat mlf $1==4 leaving cal ".mlf4" asp 4 pat mlf $1==8 leaving cal ".mlf8" asp 8 pat dvf $1==4 leaving cal ".dvf4" asp 4 pat dvf $1==8 leaving cal ".dvf8" asp 8 pat ngf $1==4 leaving cal ".ngf4" pat ngf $1==8 leaving cal ".ngf8" pat fif $1==4 leaving lor 1 cal ".fif4" asp 2 pat fif $1==8 leaving lor 1 cal ".fif8" asp 2 pat fef $1==4 leaving lor 1 adp 0-2 cal ".fef4" pat fef $1==8 leaving lor 1 adp 0-2 cal ".fef8" /********************************************/ /* Group 6: Pointer arithmetic */ /********************************************/ pat adp $1==0 /* do nothing */ pat adp $1==1 with hl_or_de gen inx %1 yields %1 pat adp $1==2 with hl_or_de gen inx %1 inx %1 yields %1 pat adp $1==0-1 with hl_or_de gen dcx %1 yields %1 pat adp $1==0-2 with hl_or_de gen dcx %1 dcx %1 yields %1 pat adp with hl_or_de uses hl_or_de={const2,$1} gen dad de yields hl pat ads $1==2 leaving adi 2 pat sbs $1==2 leaving sbi 2 /********************************************/ /* Group 7: Increment/ decrement/ zero */ /********************************************/ pat inc with hl_or_de gen inx %1 yields %1 pat inl uses hlreg={const2,$1} gen dad lb inr {m} jnz {label,1f} inx hl inr {m} 1: pat ine uses hlreg={label,$1} gen inr {m} jnz {label,1f} inx hl inr {m} 1: pat dec with hl_or_de gen dcx %1 yields %1 pat del uses hlreg={const2,$1}, dereg gen dad lb mov e,{m} inx hl mov d,{m} dcx de mov {m},d dcx hl mov {m},e pat dee uses hlreg gen lhld {label,$1} dcx hl shld {label,$1} pat zrl uses hlreg={const2,$1}, areg gen dad lb xra a mov {m},a inx hl mov {m},a pat zre uses hlreg={const2,0} gen shld {label,$1} pat zrf $1==4 leaving zer 4 pat zrf $1==8 leaving zer 8 pat zer $1==2 yields {const2,0} pat zer $1==4 yields {const2,0} {const2,0} pat zer $1<511 kills ALL uses reg={const1,$1/2}, hl_or_de={const2,0} gen 1: push %b dcr %a jnz {label,1b} pat zer kills ALL uses hl_or_de={const2,$1/2}, hl_or_de={const2,0}, areg gen xra a 1: push %b dcx %a cmp %a.2 jnz {label,1b} cmp %a.1 jnz {label,1b} /*****************************************/ /* Group 8: Convert instructions */ /*****************************************/ pat loc loc cii $1==$2 pat loc loc cii $1==2 && $2==4 with hl_or_de uses hl_or_de={const2,0}, areg gen mov a,%1.1 ora a jp {label,1f} lxi %a,{const2,0-1} 1: yields %a %1 pat loc loc cii $1==4 && $2==2 with hl_or_de hl_or_de yields %1 pat loc loc cii $1==1 && $2==2 with reg uses reusing %1, areg=%1, hl_or_de gen move {const1,0},%b.1 move a,%b.2 ora a jp {label,1f} mvi %b.1,{const1,255} 1: yields %b with hl_or_de uses areg=%1.2 gen move {const1,0},%1.1 ora a jp {label,1f} mvi %1.1,{const1,255} 1: yields %1 pat loc loc cii $1==1 && $2==4 with reg uses hlreg gen move %1,l yields hl leaving loc $1 loc $2 cii with hlreg uses dereg, areg gen move {const1,0},%1.1 move l,a ora a jp {label,1f} mvi h,{const1,255} 1: mov e,h mov d,h yields de hl pat cii kills ALL gen mvi a,{const1,1} Call {label,".cii"} pat loc loc ciu leaving loc $1 loc $2 cuu pat loc loc cui leaving loc $1 loc $2 cuu pat cui leaving cuu $1 pat ciu leaving cuu $1 pat loc loc cuu $1==$2 pat loc loc cuu $1==2 && $2==4 with src1or2 yields {const2,0} %1 pat loc loc cuu $1==4 && $1==2 with src1or2 src1or2 yields %1 pat loc loc cuu $1==1 && $2==2 with reg uses reusing %1, hl_or_de gen move %1,%a yields %a with hl_or_de gen move {const1,0},%1.1 yields %1 pat loc loc cuu $1==1 && $2==4 with reg uses reusing %1, hl_or_de gen move %1,%a yields {const2,0} %a with hl_or_de gen move {const1,0},%1.1 yields {const2,0} %1 pat cuu kills ALL gen mvi a,{const1,0} Call {label,".cii"} pat loc loc cfi $2==2 leaving loc $1 loc $2 cal ".cfi" asp 4+$1 loe ".fra" pat loc loc cfi $2==4 leaving loc $1 loc $2 cal ".cfi" asp 4+$1 lfr 4 pat loc loc cif $2==4 leaving loc $1 cal ".cif4" asp $1-2 pat loc loc cif $1==2 && $2==8 with hl_or_de gen push %1 push %1 push %1 leaving loc $1 cal ".cif8" pat loc loc cif $1==4 && $2==8 with hl_or_de hl_or_de gen push %2 push %2 push %1 leaving loc $1 cal ".cif8" pat loc loc cuf $2==4 leaving loc $1 cal ".cuf4" asp $1-2 pat loc loc cuf $1==2 && $2==8 with hl_or_de gen push %1 push %1 push %1 leaving loc $1 cal ".cuf8" pat loc loc cuf $1==4 && $2==8 with hl_or_de hl_or_de gen push %1 push %2 push %1 leaving loc $1 cal ".cuf8" pat loc loc cff $1==8 && $2==4 leaving cal ".cff4" asp 4 pat loc loc cff $1==4 && $2==8 leaving dup 4 cal ".cff8" pat loc loc cfu $2==2 leaving loc $1 loc $2 cal ".cfu" asp 4+$1 loe ".fra" pat loc loc cfu $2==4 leaving loc $1 loc $2 cal ".cfu" asp 4+$1 lfr 4 /*****************************************/ /* Group 9: Logical instructions */ /*****************************************/ pat and $1==2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ana %2.2 mov %2.2,a mov a,%1.1 ana %2.1 mov %2.1,a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ana %2.2 mov %1.2,a mov a,%1.1 ana %2.1 mov %1.1,a yields %1 pat and defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".and"} pat and !defined($1) with dereg kills ALL gen Call {label,".and"} pat ior $1==2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ora %2.2 mov %2.2,a mov a,%1.1 ora %2.1 mov %2.1,a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ora %2.2 mov %1.2,a mov a,%1.1 ora %2.1 mov %1.1,a yields %1 pat ior defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".ior"} pat ior !defined($1) with dereg kills ALL gen Call {label,".ior"} pat xor $1==2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 xra %2.2 mov %2.2,a mov a,%1.1 xra %2.1 mov %2.1,a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 xra %2.2 mov %1.2,a mov a,%1.1 xra %2.1 mov %1.1,a yields %1 pat xor defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".xor"} pat xor !defined($1) with dereg kills ALL gen Call {label,".xor"} pat com $1==2 with hl_or_de uses areg gen mov a,%1.2 cma. mov %1.2,a mov a,%1.1 cma. mov %1.1,a yields %1 pat com defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".com"} pat com !defined($1) with dereg kills ALL gen Call {label,".com"} pat rol $1==2 with dereg hlreg kills ALL uses areg gen mov a,e ani {const1,15} jz {label,3f} 1: dad hl jnc {label,2f} inr l 2: dcr a jnz {label,1b} 3: yields hl pat rol $1==4 with dereg kills ALL gen Call {label,".rol4"} pat ror $1==2 with dereg hlreg kills ALL uses areg gen mov a,e ani {const1,15} jz {label,2f} mov e,a mov a,l 1: rar. mov a,h rar. mov h,a mov a,l rar. mov l,a dcr e jnz {label,1b} 2: yields hl pat ror $1==4 with dereg kills ALL gen Call {label,".ror4"} /***********************************************/ /* Group 10: Set instructions */ /***********************************************/ pat inn $1==2 kills ALL gen Call {label,".inn2"} yields de pat inn defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".inn"} yields de pat inn !defined($1) with dereg kills ALL gen Call {label,".inn"} yields de pat set $1==2 with dereg kills ALL gen Call {label,".set2"} yields de pat set defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".set"} pat set !defined($1) with dereg kills ALL gen Call {label,".set"} /***********************************************/ /* Group 11: Array instructions */ /***********************************************/ pat lae aar $2==2 && rom($1,3)==1 && rom($1,1)==0 leaving adi 2 pat lae aar $2==2 && rom($1,3)==1 && rom($1,1)!=0 leaving adi 2 adp 0-rom($1,1) pat lae aar $2==2 && rom($1,3)==2 && rom($1,1)==0 with hlreg gen dad hl yields hl leaving adi 2 pat lae aar $2==2 && rom($1,3)==2 && rom($1,1)!=0 with hlreg uses dereg={const2,0-rom($1,1)} gen dad de dad hl yields hl leaving adi 2 pat lae aar $2==2 && rom($1,3)==4 && rom($1,1)==0 with hlreg gen dad hl dad hl yields hl leaving adi 2 pat lae aar $2==2 && rom($1,3)==4 && rom($1,1)!=0 with hlreg uses dereg={const2,0-rom($1,1)} gen dad de dad hl dad hl yields hl leaving adi 2 pat lae aar $2==2 && rom($1,3)==8 && rom($1,1)==0 with hlreg gen dad hl dad hl dad hl yields hl leaving adi 2 pat lae aar $2==2 && rom($1,3)==8 && rom($1,1)!=0 with hlreg uses dereg={const2,0-rom($1,1)} gen dad de dad hl dad hl dad hl yields hl leaving adi 2 pat lar $1==2 kills ALL gen Call {label,".lar2"} pat lar defined($1) gen Call {label,"eunimpl"} pat lar !defined($1) with hl_or_de kills ALL uses areg gen mov a,%1.2 cpi {const1,2} cnz {label,"eunimpl"} mov a,%1.1 ora a cnz {label,"eunimpl"} Call {label,".lar2"} pat sar $1==2 kills ALL gen Call {label,".sar2"} pat sar defined($1) kills ALL gen Call {label,"eunimpl"} pat sar !defined($1) with hl_or_de kills ALL uses areg gen mov a,%1.2 cpi {const1,2} cnz {label,"eunimpl"} mov a,%1.1 ora a cnz {label,"eunimpl"} Call {label,".sar2"} pat aar $1==2 kills ALL gen Call {label,".aar2"} pat aar defined($1) kills ALL gen Call {label,"eunimpl"} pat aar !defined($1) with hl_or_de kills ALL uses areg gen mov a,%1.2 cpi {const1,2} cnz {label,"eunimpl"} mov a,%1.1 ora a cnz {label,"eunimpl"} Call {label,".aar2"} /***********************************************/ /* Group 12: Compare instructions */ /***********************************************/ pat cmi $1==2 leaving sbi 2 pat cmi $1==4 kills ALL gen mvi a,{const1,1} Call {label,".cmi4"} yields de pat cmf $1==4 leaving cal ".cmf4" asp 8 lfr 2 pat cmf $1==8 leaving cal ".cmf8" asp 16 lfr 2 pat cmu $1==2 with hl_or_de hl_or_de uses areg gen mov a,%2.1 cmp %1.1 jz {label,2f} jc {label,1f} 0: lxi %2,{const2,1} jmp {label,3f} 1: lxi %2,{const2,0-1} jmp {label,3f} 2: mov a,%2.2 cmp %1.2 jc {label,1b} jnz {label,0b} lxi %2,{const2,0} 3: yields %2 pat cmu $1==4 kills ALL gen mvi a,{const1,0} Call {label,".cmi4"} yields de pat cms $1==2 leaving cmi 2 pat cms defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".cms"} yields de pat cms !defined($1) with dereg kills ALL gen Call {label,".cms"} yields de pat cmp leaving cmu 2 pat tlt with hl_or_de uses areg gen mov a,%1.1 ral. mvi a,{const1,0} mov %1.1,a adc a mov %1.2,a yields %1 pat tle with hl_or_de uses hl_or_de={const2,1}, areg gen xra a add %1.1 jm {label,2f} jnz {label,1f} xra a add %1.2 jz {label,2f} 1: dcx %a 2: yields %a pat teq with hl_or_de uses areg gen mov a,%1.1 ora %1.2 move {const2,0},%1 jnz {label,1f} inx %1 1: yields %1 pat tne with hl_or_de uses areg gen mov a,%1.1 ora %1.2 move {const2,0},%1 jz {label,1f} inx %1 1: yields %1 pat tge with hl_or_de uses areg gen mov a,%1.1 ral. cmc. mvi a,{const1,0} mov %1.1,a adc a mov %1.2,a yields %1 pat tgt with hl_or_de uses hl_or_de={const2,0}, areg gen xra a add %1.1 jm {label,2f} jnz {label,1f} xra a add %1.2 jz {label,2f} 1: inx %a 2: yields %a pat loc cmi teq and $1>=0 && $1<=255 && $2==2 && $4==2 with exact areg hl_or_de gen cpi {const1,$1} jz {label,1f} move {const2,0},%2 1: yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jz {label,2f} 1: move {const2,0},%2 2: yields %2 pat loc cmi tne and $1>=0 && $1<=255 && $2==2 && $4==2 with exact areg hl_or_de gen cpi {const1,$1} jnz {label,1f} move {const2,0},%2 1: yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jnz {label,1f} move {const2,0},%2 1: yields %2 pat loc cmi teq ior $1>=0 && $1<=255 && $2==2 && $4==2 with exact areg hl_or_de gen cpi {const1,$1} jnz {label,1f} move {const2,1},%2 1: yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jnz {label,1f} move {const2,1},%2 1: yields %2 pat loc cmi tne ior $1>=0 && $1<=255 && $2==2 && $4==2 with exact areg hl_or_de gen cpi {const1,$1} jz {label,1f} move {const2,1},%2 1: yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jz {label,2f} 1: move {const2,1},%2 2: yields %2 pat loc cmi teq $1>=0 && $1<=255 && $2==2 with exact areg uses hl_or_de={const2,0} gen cpi {const1,$1} jnz {label,1f} inx %a 1: yields %a with hl_or_de uses hl_or_de={const2,0}, areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jnz {label,1f} inx %a 1: yields %a pat loc cmi tne $1>=0 && $1<=255 && $2==2 with exact areg uses hl_or_de={const2,0} gen cpi {const1,$1} jz {label,1f} inx %a 1: yields %a with hl_or_de uses hl_or_de={const2,1}, areg gen mov a,%1.2 cpi {const1,$1} jnz {label,1f} mov a,%1.1 ora a jnz {label,1f} dcx %a 1: yields %a pat loc cmi $1>=0 && $1<=255 && $2==2 with exact areg uses hl_or_de gen sui {const1,$1} mov %a.2,a rar. mov %a.1,a yields %a with yields {const2,$1} leaving cmi 2 pat loc cmi $1<0 && $2==2 with exact areg yields {const2,0-1} with yields {const2,$1} leaving cmi 2 /*******************************************/ /* Group 13: Branch instructions */ /*******************************************/ pat loc beq $1>=0 && $1<=255 with exact reg uses reusing %1, areg=%1 gen cpi {const1,$1} jz {label,$2} with yields {const2,$1} leaving beq $2 pat loc bne $1>=0 && $1<=255 with exact reg uses reusing %1, areg=%1 gen cpi {const1,$1} jnz {label,$2} with yields {const2,$1} leaving bne $2 pat bra with STACK gen jmp {label,$1} pat blt with hl_or_de hl_or_de STACK uses areg gen mov a,%2.2 sub %1.2 mov a,%2.1 sbb %1.1 jm {label,$1} pat ble with hl_or_de hl_or_de STACK uses areg gen mov a,%1.2 sub %2.2 mov a,%1.1 sbb %2.1 jp {label,$1} pat beq with hl_or_de hl_or_de STACK uses areg gen mov a,%2.2 cmp %1.2 jnz {label,1f} mov a,%2.1 cmp %1.1 jz {label,$1} 1: pat bne with hl_or_de hl_or_de STACK uses areg gen mov a,%2.2 cmp %1.2 jnz {label,$1} mov a,%2.1 cmp %1.1 jnz {label,$1} pat bge with hl_or_de hl_or_de STACK uses areg gen mov a,%2.2 sub %1.2 mov a,%2.1 sbb %1.1 jp {label,$1} pat bgt with hl_or_de hl_or_de STACK uses areg gen mov a,%1.2 sub %2.2 mov a,%1.1 sbb %2.1 jm {label,$1} pat zlt with STACK gen pop psw ora a jm {label,$1} with hl_or_de STACK gen mov a,%1.1 ora a jm {label,$1} pat zle with hl_or_de STACK uses areg gen xra a add %1.1 jm {label,$1} jnz {label,1f} xra a add %1.2 jz {label,$1} 1: pat zeq with hl_or_de STACK uses areg gen mov a,%1.1 ora %1.2 jz {label,$1} pat zne with hl_or_de STACK uses areg gen mov a,%1.1 ora %1.2 jnz {label,$1} pat zge with STACK gen pop psw ral. jnc {label,$1} with hl_or_de STACK gen mov a,%1.1 ora a jp {label,$1} pat zgt with hl_or_de STACK uses areg gen xra a add %1.1 jm {label,1f} jnz {label,$1} xra a add %1.2 jnz {label,$1} 1: pat lol zeq with STACK uses hlreg={const2,$1}, areg gen dad lb mov a,{m} inx hl ora {m} jz {label,$2} pat lol zne with STACK uses hlreg={const2,$1}, areg gen dad lb mov a,{m} inx hl ora {m} jnz {label,$2} pat ior zeq $1==2 with hl_or_de hl_or_de STACK uses areg gen mov a,%1.1 ora %1.2 ora %2.1 ora %2.2 jz {label,$2} pat ior zne $1==2 with hl_or_de hl_or_de STACK uses areg gen mov a,%1.1 ora %1.2 ora %2.1 ora %2.2 jnz {label,$2} /*********************************************/ /* Group 14: Procedure call instructions */ /*********************************************/ pat cal kills ALL gen Call {label,$1} pat cai with hlreg kills ALL uses dereg gen lxi de,{label,1f} push de pchl. 1: pat lfr $1==2 yields de pat lfr $1<=8 with STACK uses areg={const1,$1/2}, hlreg={label,".fra"+$1}, dereg gen 1: dcx hl mov d,{m} dcx hl mov e,{m} push de dcr a jnz {label,1b} pat lfr ret $1==$2 leaving ret 0 pat ret $1==0 with STACK uses hlreg gen move lb,hl sphl. pop lb ret. pat ret $1==2 with dereg STACK uses hlreg gen move lb,hl sphl. pop lb ret. pat ret $1<=8 with STACK uses areg={const1,$1/2}, hlreg={label,".fra"}, dereg gen 1: pop de mov {m},e inx hl mov {m},d inx hl dcr a jnz {label,1b} move lb,hl sphl. pop lb ret. /******************************************/ /* Group 15: Miscellaneous */ /******************************************/ pat asp $1<=0-6 with STACK uses hlreg={const2,$1} gen dad sp sphl. pat asp $1==0-4 with STACK gen dcx sp dcx sp dcx sp dcx sp pat asp $1==0-2 with STACK gen dcx sp dcx sp pat asp $1==0 /* do nothing */ pat asp $1==2 with exact src1or2 with STACK gen inx sp inx sp pat asp $1==4 with exact src1or2 leaving asp 2 with STACK gen inx sp inx sp inx sp inx sp pat asp $1>=6 with exact src1or2 leaving asp $1-2 with STACK uses hlreg={const2,$1} gen dad sp sphl. pat ass $1==2 with hlreg STACK gen dad sp sphl. pat blm kills ALL gen lxi de,{const2,$1} Call {label,".blm"} pat bls with dereg kills ALL gen Call {label,".blm"} pat csa kills ALL gen jmp {label,".csa"} pat csb kills ALL gen jmp {label,".csb"} pat dch leaving loi 2 pat dup $1==2 with src1or2 yields %1 %1 pat dup $1==4 with src1or2 src1or2 yields %2 %1 %2 %1 pat dup kills ALL gen lxi de,{const2,$1} Call {label,".dup"} pat dus $1==2 with dereg kills ALL gen Call {label,".dup"} pat exg $1==2 with src1or2 src1or2 yields %1 %2 pat exg defined($1) kills ALL gen lxi de,{const2,$1} Call {label,".exg"} pat fil uses hlreg={label,$1} gen shld {label,"hol0"+4} pat gto with STACK gen lhld {label,$1+2} sphl. lhld {label,$1+4} move hl,lb lhld {label,$1} pchl. pat lim uses hlreg gen lhld {label,".ignmask"} yields hl pat lin uses hlreg={const2,$1} gen shld {label,"hol0"} pat lni uses hlreg gen lhld {label,"hol0"} inx hl shld {label,"hol0"} pat lor $1==0 yields lb pat lor $1==1 with STACK uses hlreg={const2,0} gen dad sp yields hl pat lor $1==2 uses hlreg gen lhld {label,".reghp"} yields hl pat lpb leaving adp SL pat mon kills ALL gen Call {label,".mon"} pat nop kills ALL #ifdef DEBUG gen Call {label,".nop"} #endif pat rck with hl_or_de STACK pat rtt leaving ret 0 pat sig with dereg uses hlreg gen lhld {label,".trapproc"} xchg. shld {label,".trapproc"} yields de with STACK uses hlreg gen lhld {label,".trapproc"} xthl. shld {label,".trapproc"} pat sim with hlreg gen shld {label,".ignmask"} pat str $1==0 with localbase pat str $1==1 with hlreg gen sphl. pat str $1==2 with hlreg gen shld {label,".reghp"} pat trp kills ALL gen Call {label,".trp"}