/************************************************************/
/************************************************************/
/*******					       ******/
/*******   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
with STACK
uses dereg={const2,$1}
gen Call {label,".loi"}

pat los $1==2
with dereg STACK
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
with STACK
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 STACK
   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 STACK
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
with STACK
uses dereg={const2,$1}
gen Call {label,".sti"}

pat sts $1==2
with dereg STACK
gen Call {label,".sti"}

pat sdl
with dereg STACK
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 STACK
gen shld {label,$1}
    pop hl
    shld {label,$1+2}
with hlreg dereg STACK
gen shld {label,$1}
    xchg.
    shld {label,$1+2}
with dereg hlreg STACK
gen shld {label,$1+2}
    xchg.
    shld {label,$1}

pat sdf
with hl_or_de STACK
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
with STACK
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
with STACK
gen Call {label,".sbi4"}

pat mli $1==2
with STACK
gen Call {label,".mli2"}		yields de

pat mli $1==4
with STACK
gen Call {label,".mli4"}

pat dvi $1==2
with STACK
uses areg={const1,129}
gen Call {label,".dvi2"}		yields de

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

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

pat rmi $1==4
with STACK
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
with STACK
gen Call {label,".ngi4"}

pat sli $1==2
with STACK
gen Call {label,".sli2"}		yields de

pat sli $1==4
with STACK
gen Call {label,".sli4"}

pat sri $1==2
with STACK
uses areg={const1,1}
gen Call {label,".sri2"}		yields de

pat sri $1==4
with STACK
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
with STACK
gen Call {label,".mlu2"}		yields de

pat mlu $1==4
with STACK
gen Call {label,".mli4"}

pat dvu $1==2
with STACK
uses areg={const1,1}
gen Call {label,".dvi2"}		yields de

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

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

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

pat slu						leaving sli $1

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

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


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

/* Floating points are not supported */

pat adf			gen Call {label,"eunimpl"}
pat sbf			gen Call {label,"eunimpl"}
pat mlf			gen Call {label,"eunimpl"}
pat dvf			gen Call {label,"eunimpl"}
pat ngf			gen Call {label,"eunimpl"}
pat fif			gen Call {label,"eunimpl"}
pat fef			gen Call {label,"eunimpl"}

/********************************************/
/* 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			gen Call {label,"eunimpl"}

pat zer $1==2				yields {const2,0}

pat zer $1==4				yields {const2,0} {const2,0}

pat zer $1<511
with STACK
uses reg={const1,$1/2}, hl_or_de={const2,0}
gen 1:
    push %b
    dcr %a
    jnz {label,1b}

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

pat cfi			gen Call {label,"eunimpl"}
pat cif			gen Call {label,"eunimpl"}
pat cuf			gen Call {label,"eunimpl"}
pat cff			gen Call {label,"eunimpl"}
pat cfu			gen Call {label,"eunimpl"}
 
/*****************************************/
/* 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)
with STACK
uses dereg={const2,$1}
gen Call {label,".and"}

pat and !defined($1)
with dereg STACK
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)
with STACK
uses dereg={const2,$1}
gen Call {label,".ior"}

pat ior !defined($1)
with dereg STACK
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)
with STACK
uses dereg={const2,$1}
gen Call {label,".xor"}

pat xor !defined($1)
with dereg STACK
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)
with STACK
uses dereg={const2,$1}
gen Call {label,".com"}

pat com !defined($1)
with dereg STACK
gen Call {label,".com"}

pat rol $1==2
with dereg hlreg STACK
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 STACK
gen Call {label,".rol4"}

pat ror $1==2
with dereg hlreg STACK
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 STACK
gen Call {label,".ror4"}

/***********************************************/
/* Group 10: Set instructions		       */
/***********************************************/

pat inn $1==2
with STACK
gen Call {label,".inn2"}		yields de

pat inn defined($1)
with STACK
uses dereg={const2,$1}
gen Call {label,".inn"}			yields de

pat inn !defined($1)
with dereg STACK
gen Call {label,".inn"}			yields de

pat set $1==2
with dereg STACK
gen Call {label,".set2"}		yields de

pat set defined($1)
with STACK
uses dereg={const2,$1}
gen Call {label,".set"}

pat set !defined($1)
with dereg STACK
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
with STACK
gen Call {label,".lar2"}

pat lar defined($1)
gen Call {label,"eunimpl"}

pat lar !defined($1)
with hl_or_de STACK
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
with STACK
gen Call {label,".sar2"}

pat sar defined($1)
gen Call {label,"eunimpl"}

pat sar !defined($1)
with hl_or_de STACK
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
with STACK
gen Call {label,".aar2"}

pat aar defined($1)
gen Call {label,"eunimpl"}

pat aar !defined($1)
with hl_or_de STACK
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
with STACK
uses areg={const1,1}
gen Call {label,".cmi4"}		yields de

pat cmf			gen Call {label,"eunimpl"}
 
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
with STACK
uses areg={const1,0}
gen Call {label,".cmi4"}		yields de

pat cms $1==2					leaving cmi 2

pat cms defined($1)
with STACK
uses dereg={const2,$1}
gen Call {label,".cms"}			yields de

pat cms !defined($1)
with dereg STACK
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
with STACK
gen Call {label,$1}

pat cai
with hlreg STACK
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
with STACK
uses dereg={const2,$1}
gen Call {label,".blm"}

pat bls
with dereg STACK
gen Call {label,".blm"}

pat csa
with STACK
gen jmp {label,".csa"}

pat csb
with STACK
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
with STACK
uses dereg={const2,$1}
gen Call {label,".dup"}

pat dus $1==2
with dereg STACK
gen Call {label,".dup"}

pat exg $1==2
with src1or2 src1or2			yields %1 %2

pat exg defined($1)
with STACK
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
with STACK
gen Call {label,".mon"}

pat nop
with STACK
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
with STACK
gen Call {label,".trp"}
