/************************************************************/ /************************************************************/ /******* ******/ /******* 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 STACKHELPERS=128 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. largeconst2 = { INT num; } 2 num. /* Word-sized constant with low byte zero */ smallpconst2 = { INT num; } 2 num. /* Byte-sized positive constant */ smallnconst2 = { INT num; } 2 num. /* Byte-sized negative constant */ label = { ADDR off; } 2 off. plabel = { ADDR off; INT param; } 2 off param. m = { } 2 cost(0,3) "m". comment = { ADDR str; } 2 "! " str. SETS reg1 = reg + lbreg + m. b_d_h_sp = regpair + stackpointer. b_d_h_psw = regpair + psword. immediate = largeconst2 + smallpconst2 + smallnconst2 + const2 + label. src1 = reg. src2 = hl_or_de + const2 + label. src1or2 = src1 + src2. anyreg = reg + regpair. 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 "call" plabel: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). */ data1 ".data1" const1:ro. data2 ".data2" const2:ro. 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 comment:ro 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). kill anyreg:rw kills :cc cost(0, 0). 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 const1 to reg gen mvi %2, %1 from const1 to regpair gen mvi %2.2, %1 mvi %2.1, {const1, 0} 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=%1 yields %a from hl_or_de uses hl_or_de gen xchg. yields %a from regpair uses regpair=%1 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 largeconst2 yields {const2, %1.num} from smallpconst2 yields {const2, %1.num} from smallnconst2 yields {const2, %1.num} from const2 uses hl_or_de=%1 yields %a from largeconst2 uses hl_or_de=%1 yields %a from smallpconst2 uses reg={const1, %1.num & 0xff} yields %a from smallnconst2 uses reg={const1, %1.num & 0xff} yields %a from smallpconst2 %1.num == 1 uses reg={const1, 0} gen inr %a yields %a from smallnconst2 %1.num == 0-1 uses reg={const1, 0} gen dcr %a yields %a from const2 uses reg={const1, %1.num & 0xff} yields %a from hl_or_de uses reg=%1.2 yields %a PATTERNS /*********************************************/ /* Group 1: Load instructions */ /*********************************************/ pat loc ($1 != 0) && (($1 & 0xff) == 0) yields {largeconst2, $1} pat loc ufit($1, 8) yields {smallpconst2, $1} pat loc sfit($1, 8) && ($1<0) yields {smallnconst2, $1} pat loc yields {const2, $1} pat ldc yields {const2, highw($1)} {const2, loww($1)} #ifdef USE_I80_RSTS pat lol $1==0-2 uses dereg, hlreg gen rst {const1, 1} yields de pat lol $1==0-4 uses dereg, hlreg gen rst {const1, 2} yields de pat lol $1==4 uses dereg, hlreg gen rst {const1, 3} yields de #endif pat lol ($1>0) && ($1<=STACKHELPERS) uses dereg, hlreg gen Call {plabel, ".fload", $1} yields de pat lol ($1<0) && ($1>=0-STACKHELPERS) uses dereg, hlreg gen Call {plabel, ".floadn", 0-$1} yields de pat lol uses dereg, hlreg={const2, $1} 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 leaving lol $1 loi 2 pat lof leaving adp $1 loi 2 pat lal ($1>0) && ($1<=STACKHELPERS) uses hlreg gen Call {plabel, ".faddr", $1} yields hl pat lal ($1<0) && ($1>=0-STACKHELPERS) uses hlreg gen Call {plabel, ".faddrn", 0-$1} yields hl 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 leaving lxa 0 loi 2 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 leaving lal $1 loi 4 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 leaving adp $1 loi 4 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 #ifdef USE_I80_RSTS pat stl $1==0-2 with dereg uses hlreg gen rst {const1, 4} #endif pat stl ($1>0) && ($1<=STACKHELPERS) with dereg uses hlreg gen Call {plabel, ".fstore", $1} pat stl ($1<0) && ($1>=0-STACKHELPERS) with dereg uses hlreg gen Call {plabel, ".fstoren", 0-$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 leaving lol $1 sti 2 pat sil lil $1==$2 leaving dup 2 lol $1 sti 2 pat lil inc sil $1==$3 leaving lol $1 dup 2 loi 2 inc 2 exg 2 sti 2 pat lil inc sil $1==$3 leaving lol $1 dup 2 loi 2 dec 2 exg 2 sti 2 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 %1 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 leaving lal $1 sti 4 pat sdf leaving adp $1 sti 4 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} /****************************************/ /* Group 3: Integer arithmetic */ /****************************************/ pat adi $1==2 with hl_or_de largeconst2 uses areg gen mov a, %1.1 adi {const1, %2.num >> 8} mov %1.1, a kill a yields %1 with largeconst2 hl_or_de yields %1 %2 leaving adi 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 const2 hl_or_de yields %2 {const2, 0-%1.num} leaving adi 2 with largeconst2 hl_or_de yields %2 {largeconst2, 0-%1.num} leaving adi 2 with smallpconst2 hl_or_de yields %2 {smallnconst2, 0-%1.num} leaving adi 2 with smallnconst2 hl_or_de yields %2 {smallpconst2, 0-%1.num} leaving adi 2 with hl_or_de const2 uses areg gen mvi a, {const1, %2.num & 0xff} sub %1.2 mov %1.2, a mvi a, {const1, %2.num >> 8} sbb %1.1 mov %1.1, a kill a yields %1 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 kill 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 kill 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==1) && ($2==2) with hlreg gen dad hl yields hl pat loc sli ($1>=2) && ($1<=7) && ($2==2) with hlreg gen dad hl yields hl leaving loc $1-1 sli 2 pat loc sli ($1==8) && ($2==2) with hl_or_de gen mov %1.1, %1.2 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 loc slu ($2==2) leaving loc $1 sli $2 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 ($1>0) && ($1<=STACKHELPERS) uses hlreg gen Call {plabel, ".faddr", $1} inr {m} jnz {label,1f} inx hl inr {m} 1: pat inl ($1<0) && ($1>=0-STACKHELPERS) uses hlreg gen Call {plabel, ".faddrn", 0-$1} inr {m} jnz {label,1f} inx hl inr {m} 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 kills dereg, hlreg uses hlreg={const2,$1} 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, areg gen mov a, %1.1 ral. sbb a mov %a.1, a mov %a.2, a 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 mov %b.2, a ral. sbb a mov %b.1, a yields %b with hl_or_de uses areg=%1.2 gen ral. sbb a mov %1.1, a yields %1 pat loc loc cii $1==1 && $2==4 with areg uses hl_or_de, hl_or_de gen mov %b.2, a ral. sbb a mov %b.1, a mov %a.2, a mov %a.1, a yields %a %b with hlreg uses dereg, areg gen mov a, l ral. sbb a mov h, a mov e, a mov d, a 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 yields %1 pat loc loc cuu $1==1 && $2==4 with reg uses reusing %1 yields {const2,0} %1 with hl_or_de 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 loc and ($1==0xff) && ($2==2) with hl_or_de yields %1.2 pat loc and ($1==0xffff) && ($2==2) pat and $1==2 with hl_or_de smallpconst2 uses areg gen mov a, %1.2 ani {const1, %2.num & 0xff} yields a with smallpconst2 hl_or_de yields %1 %2 leaving and 2 with hl_or_de smallnconst2 uses areg gen mov a, %1.2 ani {const1, %2.num & 0xff} mov %1.2, a kill a yields %1 with smallnconst2 hl_or_de yields %1 %2 leaving and 2 with hl_or_de const2 uses areg gen mov a, %1.2 ani {const1, %2.num & 0xff} mov %1.2, a kill a mov a, %1.1 ani {const1, %2.num >> 8} mov %1.1, a kill a yields %1 with const2 hl_or_de yields %1 %2 leaving and 2 with hl_or_de hl_or_de uses areg gen mov a, %1.2 ana %2.2 mov %2.2, a kill a mov a, %1.1 ana %2.1 mov %2.1, a kill a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ana %2.2 mov %1.2,a kill a mov a,%1.1 ana %2.1 mov %1.1,a kill 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 loc ior ($1==0) pat ior $1==2 with hl_or_de smallpconst2 uses areg gen mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a kill a yields %1 with smallpconst2 hl_or_de yields %1 %2 leaving ior 2 with hl_or_de smallnconst2 uses areg gen mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a kill a move {const1, 0xff}, %1.1 yields %1 with smallnconst2 hl_or_de yields %1 %2 leaving ior 2 with hl_or_de const2 uses areg gen mov a, %1.2 ori {const1, %2.num & 0xff} mov %1.2, a kill a mov a, %1.1 ori {const1, %2.num >> 8} mov %1.1, a kill a yields %1 with const2 hl_or_de yields %1 %2 leaving ior 2 with hl_or_de hl_or_de uses areg gen mov a, %1.2 ora %2.2 mov %2.2, a kill a mov a, %1.1 ora %2.1 mov %2.1, a kill a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 ora %2.2 mov %1.2,a kill a mov a,%1.1 ora %2.1 mov %1.1,a kill 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 loc xor ($1==0) pat xor $1==2 with hl_or_de smallpconst2 uses areg gen mov a, %1.2 xri {const1, %2.num & 0xff} mov %1.2, a kill a yields %1 with smallpconst2 hl_or_de yields %1 %2 leaving xor 2 with hl_or_de const2 uses areg gen mov a, %1.2 xri {const1, %2.num & 0xff} mov %1.2, a kill a mov a, %1.1 xri {const1, %2.num >> 8} mov %1.1, a kill a yields %1 with const2 hl_or_de yields %1 %2 leaving xor 2 with hl_or_de hl_or_de uses areg gen mov a, %1.2 xra %2.2 mov %2.2, a kill a mov a, %1.1 xra %2.1 mov %2.1, a kill a yields %2 with hl_or_de hl_or_de uses areg gen mov a,%1.2 xra %2.2 mov %1.2,a kill a mov a,%1.1 xra %2.1 mov %1.1,a kill 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 kill 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 zlt $1==2 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 jc {label, $2} with const2 hl_or_de STACK uses areg gen mov a, %2.2 sui {const1, %1.num & 0xff} mov a, %2.1 sbi {const1, %1.num >> 8} jc {label, $2} with hl_or_de const2 STACK uses areg gen mvi a, {const1, %2.num & 0xff} sub %1.2 mvi a, {const1, %2.num >> 8} sbb %1.1 jc {label, $2} pat cmu zgt $1==2 leaving exg 2 cmu 2 zlt $2 pat cmu zge $1==2 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 jnc {label, $2} with const2 hl_or_de STACK uses areg gen mov a, %2.2 sui {const1, %1.num & 0xff} mov a, %2.1 sbi {const1, %1.num >> 8} jnc {label, $2} with hl_or_de const2 STACK uses areg gen mvi a, {const1, %2.num & 0xff} sub %1.2 mvi a, {const1, %2.num >> 8} sbb %1.1 jnc {label, $2} pat cmu zle $1==2 leaving exg 2 cmu 2 zge $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 hlreg dereg STACK uses areg gen #ifdef USE_I80_RSTS rst {const1, 5} #else Call {label, ".cmps_mag"} #endif jc {label, $1} pat bgt leaving exg 2 blt $1 pat bge with hlreg dereg STACK uses areg gen #ifdef USE_I80_RSTS rst {const1, 5} #else Call {label, ".cmps_mag"} #endif jnc {label, $1} pat ble leaving exg 2 bge $1 pat beq with const2 hl_or_de STACK uses areg gen mov a, %2.2 cpi {const1, %1.num & 0xff} jnz {label, 1f} mov a, %2.1 cpi {const1, %1.num >> 8} jz {label, $1} 1: with hl_or_de const2 STACK leaving exg 2 beq $1 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 const2 hl_or_de STACK uses areg gen mov a, %2.2 cpi {const1, %1.num & 0xff} jnz {label, $1} mov a, %2.1 cpi {const1, %1.num >> 8} jnz {label, $1} with hl_or_de const2 STACK leaving exg 2 beq $1 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 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 mov a, %1.1 ora a jm {label, $1} jnz {label, 1f} ora %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 mov a, %1.1 ora a jm {label, 1f} jnz {label, $1} ora %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 gen Call {label, ".pchl"} 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 jmp {label, ".ret"} pat ret $1==2 with dereg STACK uses hlreg gen jmp {label, ".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} jmp {label, ".ret"} /******************************************/ /* Group 15: Miscellaneous */ /******************************************/ pat asp $1==0 /* do nothing */ pat asp ($1==2) with hl_or_de with STACK uses hlreg gen pop hl pat asp ($1==4) with hl_or_de hl_or_de with STACK uses hlreg gen pop hl pop hl pat asp ($1<0) && ($1>0-12) with STACK gen push hl leaving asp $1+2 pat asp ($1>4) && ($1<12) with STACK uses hlreg gen pop hl leaving asp $1-2 pat asp 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 with areg kills ALL gen Call {label,".trp"}