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