/************************************************************/
/************************************************************/
/*******					       ******/
/*******   8 0 8 0    B A C K  E N D   T A B L E       ******/
/*******					       ******/
/************************************************************/
/************************************************************/


rcsid = "$Header$"

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 lol $1==$2
uses hlreg={const2,$1}, dereg
gen dad lb
    mov e,{m}
    inx hl
    mov d,{m}				yields de de

pat lol
uses hlreg={const2,$1}, dereg
gen dad lb
    mov e,{m}
    inx hl
    mov d,{m}				yields de

pat loe loe $1==$2
uses hlreg
gen lhld {label,$1}			yields hl hl

pat loe
uses hlreg
gen lhld {label,$1}			yields hl

pat lil lil $1==$2
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 de

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}
gen 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
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
uses dereg={const2,$1}
gen 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}
gen Call {label,".dvi2"}		yields de

pat dvi $1==4
kills ALL
uses areg={const1,129}
gen Call {label,".dvi4"}

pat rmi $1==2
kills ALL
uses areg={const1,128}
gen Call {label,".dvi2"}		yields de

pat rmi $1==4
kills ALL
uses areg={const1,128}
gen 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 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
uses areg={const1,1}
gen Call {label,".sri2"}		yields de

pat sri $1==4
kills ALL
uses areg={const1,1}
gen 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
uses areg={const1,1}
gen Call {label,".dvi2"}		yields de

pat dvu $1==4
kills ALL
uses areg={const1,1}
gen Call {label,".dvi4"}

pat rmu $1==2
kills ALL
uses areg={const1,0}
gen Call {label,".dvi2"}		yields de

pat rmu $1==4
kills ALL
uses areg={const1,0}
gen Call {label,".dvi4"}

pat slu						leaving sli $1

pat sru $1==2
kills ALL
uses areg={const1,0}
gen Call {label,".sri2"}		yields de

pat sru $1==4
kills ALL
uses areg={const1,0}
gen Call {label,".sri4"}


/********************************************/
/* Group 5: Floating point arithmetic	    */
/********************************************/

pat adf $1==4
kills ALL
gen Call {label,".adf4"}

pat adf $1==8
kills ALL
gen Call {label,".adf8"}

pat sbf $1==4
kills ALL
gen Call {label,".sbf4"}

pat sbf $1==8
kills ALL
gen Call {label,".sbf8"}

pat mlf $1==4
kills ALL
gen Call {label,".mlf4"}

pat mlf $1==8
kills ALL
gen Call {label,".mlf8"}

pat dvf $1==4
kills ALL
gen Call {label,".dvf4"}

pat dvf $1==8
kills ALL
gen Call {label,".dvf8"}

pat ngf $1==4
kills ALL
gen Call {label,".ngf4"}

pat ngf $1==8
kills ALL
gen Call {label,".ngf8"}

pat fif $1==4
kills ALL
gen Call {label,".fif4"}

pat fif $1==8
kills ALL
gen Call {label,".fif8"}

pat fef $1==4
kills ALL
gen Call {label,".fef4"}

pat fef $1==8
kills ALL
gen Call {label,".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
kills ALL
gen Call {label,".zrf4"}

pat zrf $1==8
kills ALL
gen Call {label,".zrf8"}

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
uses areg={const1,1}
gen 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
uses areg={const1,0}
gen Call {label,".cii"}

pat cfi
kills ALL
gen Call {label,".cfi"}

pat cif
kills ALL
gen Call {label,".cif"}

pat cuf
kills ALL
gen Call {label,".cuf"}

pat cff
kills ALL
gen Call {label,".cff"}

pat cfu
kills ALL
gen Call {label,".cfu"}

/*****************************************/
/* 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses areg={const1,1}
gen Call {label,".cmi4"}		yields de

pat cmf $1==4
kills ALL
gen Call {label,".cmf4"}

pat cmf $1==8
kills ALL
gen Call {label,".cmf8"}
 
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
uses areg={const1,0}
gen Call {label,".cmi4"}		yields de

pat cms $1==2					leaving cmi 2

pat cms defined($1)
kills ALL
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,$1}
gen 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
uses dereg={const2,1}
gen 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
gen Call {label,".nop"}

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"}