rcsid = "$Header$"

/*****************************************************************
 *								 *
 *       N S  1 6 0 3 2    B A C K - E N D  T A B L E		 *
 *								 *
 *								 *
 *	Author: Annita Wilschut.				 *
 *								 *
 *****************************************************************/

/*
 * Deze tabel implementeert, naast gewone, ook floating point
 * instructies. Bij gebrek aan een floating point processor
 * is het betreffende onderdeel van de tabel echter niet 
 * getest. Wanneer NOFLOAT "aan" is worden er zeker geen
 * floating point instructies gegenereerd. Na verwijdering van
 * alle ifdef's worden er bij de vertaling van een programma dat
 * geen floating point gebruikt, hoogst waarschhijnlijk ook
 * geen floating point instructies gegenereerd. Dit is echter niet 
 * uitgebreid getest.
 */

EM_WSIZE=4
EM_PSIZE=4
EM_BSIZE=8

#define NOFLOAT

PROPERTIES

USELESS			/* Bug circumvention */
REG			/* Normal registers */
FREG			/* Floating point registers */
DFREG(8)		/* double floating reg for double precision */
MEMREG			/* sp, fp en sb */
REGPAIR(8)		/* register pair for extended integer instr */
PROGRAMCOUNTER
STACKPOINTER
STATICBASE
LOCALBASE


REGISTERS

r0,r1,r2,r7		: REG.
r3,r4,r5,r6		: REG regvar .
f0,f1,f2,f3,f4,f5,f6,f7		: FREG.
f01("f0")=f0+f1,
f23("f2")=f2+f3,
f45("f4")=f4+f5,
f67("f6")=f6+f7			: DFREG.
r01("r0")=r0+r1,r23("r2")=r2+r3 : REGPAIR.
sp				: STACKPOINTER, MEMREG.
pc				: PROGRAMCOUNTER.
fp				: LOCALBASE, MEMREG.
sb				: STATICBASE, MEMREG.


TOKENS

const4		= { INT num; } 4 num .
LOCAL		= { INT ind;}  4 ind "(fp)" .
DLOCAL		= { INT ind;} 8 ind "(fp)".


addr_local	= { INT ind; } 4 .
addr_external	= { ADDR disp; } 4 disp .

regrel1		= { REG reg; ADDR disp; } 4 disp "(" reg ")" .
regrel2		= { REG reg; ADDR disp; } 4 disp "(" reg ")" .
regrel4		= { REG reg; ADDR disp; } 4 disp "(" reg ")" .
regrel8		= { REG reg; ADDR disp; } 8 disp "(" reg ")" .
memregrel1	= { MEMREG reg; ADDR disp; } 4 disp "(" reg ")" .
memregrel2	= { MEMREG reg; ADDR disp; } 4 disp "(" reg ")" .
memregrel4	= { MEMREG reg; ADDR disp; } 4 disp "(" reg ")" .
memregrel8	= { MEMREG reg; ADDR disp; } 8 disp "(" reg ")" .
memrel1		= { MEMREG reg; ADDR disp1; ADDR disp2; } 4 disp2 "("
			disp1 "(" reg "))" .
memrel2		= { MEMREG reg; ADDR disp1; ADDR disp2; } 4 disp2 "("
			disp1 "(" reg "))" .
memrel4		= { MEMREG reg; ADDR disp1; ADDR disp2; } 4 disp2 "("
			disp1 "(" reg "))" .
memrel8		= { MEMREG reg; ADDR disp1; ADDR disp2; } 8 disp2 "("
			disp1 "(" reg "))" .
absolute1	= { ADDR disp; } 4 "@" disp .
absolute2	= { ADDR disp; } 4 "@" disp .
absolute4	= { ADDR disp; } 4 "@" disp .
absolute8	= { ADDR disp; } 8 "@" disp .
TOS		= {} 4 "tos" .

regcon4		= { REG reg; ADDR disp; } 4 .
memregcon4	= { MEMREG reg; ADDR disp; } 4 .
memregrelcon4	= { MEMREG reg; ADDR disp1; ADDR disp2;} 4 .

label		= {ADDR disp; } 4 disp .

memregrelsid	= {INT ind; MEMREG reg1; REG reg2; } 4 ind "(" reg1 
			")[" reg2 ":d]" .
abssid		= {ADDR disp; REG reg; } 4 "@" disp "[" reg ":d]" .
fprelsid	= {ADDR disp1; ADDR disp2; REG reg; } 4
			disp2 "(" disp1 "(fp))[" reg ":d]" .
sprelsid	= {ADDR disp1; ADDR disp2; REG reg; } 4
			disp2 "(" disp1 "(sp))[" reg ":d]" .

SETS

src1		= regrel1 + memregrel1 + memrel1 + absolute1 .
src2		= regrel2 + memregrel2 + memrel2 + absolute2 .
src4		= REG + const4 + LOCAL + regrel4 + memrel4 + 
	       	  memregrel4 + memregrelsid + abssid + absolute4 + 
		  addr_external.
con4		= regcon4 + memregcon4 + memregrelcon4 .
tossrc4		= TOS + src4 .
consrc4		= con4 + src4 .
fsrc4		= FREG + LOCAL + regrel4 + memrel4 + 
	       	  memregrel4 + memregrelsid + abssid + absolute4 . 
tosfsrc4	= TOS + fsrc4 .
fsrc8		= DFREG + DLOCAL + regrel8 + memrel8 + 
	       	  memregrel8 + absolute8 . 
tosfsrc8	= TOS + fsrc8 .
dst1		= src1 .
tosdst1		= TOS + dst1 .
dst2		= src2 .
tosdst2		= TOS + dst2 .
dst4		= REG + LOCAL + regrel4 + memregrel4 + memrel4 + 
		  absolute4 + memregrelsid + abssid .
tosdst4		= TOS + dst4 .
fdst4		= FREG + LOCAL + regrel4 + memregrel4 + memrel4 + 
		  absolute4 + memregrelsid + abssid .
tosfdst4	= TOS + fdst4 .
fdst8		= fsrc8 .
tosfdst8	= tosfsrc8 .
regrel		= regrel1 + regrel2 + regrel4 +regrel8 .
memregrel	= memregrel1 + memregrel2 + memregrel4 +memregrel8 .
memrel		= memrel1 + memrel2 + memrel4 +memrel8 .
rel		= regrel + memregrel + memrel + memregrelsid 
		   + fprelsid + sprelsid .
absolute	= absolute1 + absolute2 + absolute4 + absolute8 + abssid .
regs		= REG + FREG + DFREG + MEMREG + REGPAIR .
allmincon	= ALL - (regs + const4 + addr_local + addr_external
		  + regcon4 + memregcon4) .
src24		= src2 + src4 .
src124		= src1 + src2 + src4 .
tossrc24	= TOS + src24 .
tossrc124	= TOS + src124 .


INSTRUCTIONS


movb tossrc124:ro, tosdst1:wo .
movw tossrc24:ro, tosdst2:wo .
movd tossrc4:ro, tosdst4:wo .
movf tosfsrc4:ro, tosfdst4:wo .
movl tosfsrc8:ro, tosfdst8:wo .
movdf tossrc4:ro, tosfdst4:wo .
movdl tossrc4:ro, tosfdst8:wo .
movfl tosfsrc4:ro, tosfdst8:wo .
movlf tosfsrc8:ro, tosfdst4:wo .
truncfd tosfsrc4:ro, tosdst4:wo .
truncld tosfsrc8:ro, tosdst4:wo .
cmpb tossrc124:ro, src1:ro .
cmpw tossrc24:ro, src2:ro .
cmpd tossrc4:ro, tossrc4:ro .
cmpf tosfsrc4:ro, tosfsrc4:ro .
cmpl tosfsrc8:ro, tosfsrc8:ro .
addd tossrc4:ro, tosdst4:rw .
addcd tossrc4:ro, tosdst4:rw .
addf tosfsrc4:ro, tosfdst4:rw .
addl tosfsrc8:ro, tosfdst8:rw .
subd tossrc4:ro, tosdst4:rw .
subcd tossrc4:ro, tosdst4:rw .
subf tosfsrc4:ro, tosfdst4:rw .
subl tosfsrc8:ro, tosfdst8:rw .
muld tossrc4:ro, tosdst4:rw .
mulf tosfsrc4:ro, tosfdst4:rw .
mull tosfsrc8:ro, tosfdst8:rw .
quod tossrc4:ro, tosdst4:rw .
divd tossrc4:ro, tosdst4:rw .
divf tosfsrc4:ro, tosfdst4:rw .
divl tosfsrc8:ro, tosfdst8:rw .
remd tossrc4:ro, tosdst4:rw .
modd tossrc4:ro, tosdst4:rw .
negd tossrc4:ro, tosdst4:wo .
negf tosfsrc4:ro, tosfdst4:wo .
negl tosfsrc8:ro, tosfdst8:wo .
roundfd tosfsrc4:ro, tosdst4:wo .
roundld tosfsrc8:ro, tosdst4:wo .
andd tossrc4:ro, tosdst4:wo .
ord tossrc4:ro, tosdst4:wo .
xord tossrc4:ro, tosdst4:rw .
comd tossrc4:ro, tosdst4:rw .
ashd tossrc124:ro, tosdst4:rw .
lshd tossrc124:ro, tosdst4:rw .
rotd tossrc124:ro, tosdst4:rw .
movzbd tossrc124:ro, tosdst4:wo .
movzwd tossrc24:ro, tosdst4:wo .
movxbd tossrc124:ro, tosdst4:wo .
movxwd tossrc124:ro, tosdst4:wo .
addr tosdst4:ro, tosdst4:wo .
movqd const4:ro, tosdst4:wo .
cmpqd const4:ro, tossrc4:ro .
meid tossrc4:ro, REGPAIR:rw .
sxx tosdst4:wo .
seqd tosdst4:wo .
sned tosdst4:wo .
sltd tosdst4:wo .
sled tosdst4:wo .
sgtd tosdst4:wo .
sged tosdst4:wo .
shid tosdst4:wo .
sfsd tosdst4:wo .
tbitd tossrc4:ro, tosdst4:ro .
cbitd tossrc4:ro, tosdst4:rw .
sbitd tossrc4:ro, tosdst4:rw .
movmd tosdst4:ro, tosdst4:rw, const4 .
indexd REG, tossrc4:ro, tossrc4:ro .
brxx label .
beq label .
bne label .
ble label .
blt label .
bge label .
bgt label .
bfc label .
bfs label .
blo label .
bls label .
bhs label .
bhi label .
br label .
acbd const4:ro, tosdst4:rw, label .
jsr tosdst4+label .
ret const4:ro .
adjspd tossrc4:ro .
exit label .
sprd tossrc4:ro, MEMREG:rw .



MOVES


from memregrelcon4 to tosdst4
gen addr {memrel4, %1.reg, %1.disp1, %1.disp2}, %2

from regcon4 to tosdst4
gen addr {regrel4, %1.reg, %1.disp}, %2

from memregcon4 to tosdst4
gen addr {memregrel4, %1.reg, %1.disp}, %2

from tossrc4 to tosdst4
gen movd %1, %2

from tossrc124 to tosdst1
gen movb %1, %2

from tossrc24 to tosdst2
gen movw %1, %2

#ifndef NOFLOAT
from tosfsrc4 to FREG
gen movf %1, %2

from FREG to tosfdst4
gen movf %1, %2

from tosfsrc8 to DFREG
gen movl %1, %2

from DFREG to tosfdst8
gen movl %1, %2
#endif


STACKINGRULES


from src1 to STACK
gen movzbd %1, {TOS}

from src2 to STACK
gen movzwd %1, {TOS}

from src4 to STACK
gen movd %1, {TOS}

#ifndef NOFLOAT
from FREG to STACK
gen movf %1, {TOS}

from DFREG to STACK
gen movl %1, {TOS}
#endif

from MEMREG to STACK
gen addr {memregrel4, %1, 0}, {TOS}

from addr_local to STACK
gen addr {memregrel4, fp, %1.ind}, {TOS}
 
from regcon4 to STACK
gen addr {regrel4, %1.reg, %1.disp}, {TOS}

from memregcon4 to STACK
gen addr {memregrel4, %1.reg, %1.disp}, {TOS}

from memregrelcon4 to STACK
gen addr {memrel4, %1.reg, %1.disp1, %1.disp2}, {TOS}

from DLOCAL to STACK
gen movd {LOCAL,  %1.ind+4}, {TOS}
    movd {LOCAL, %1.ind}, {TOS}

from absolute8 to STACK
gen movd {absolute4, %1.disp+4}, {TOS}
    movd {absolute4, %1.disp}, {TOS}

from memrel8 to STACK
gen movd {memrel4, %1.reg, %1.disp1, %1.disp2+4}, {TOS}
    movd {memrel4, %1.reg, %1.disp1, %1.disp2}, {TOS}

from regrel8 to STACK
gen movd {regrel4, %1.reg, %1.disp+4}, {TOS}
    movd {regrel4, %1.reg, %1.disp}, {TOS}

from memregrel8 to STACK
gen movd {memregrel4, %1.reg, %1.disp+4}, {TOS}
    movd {memregrel4, %1.reg, %1.disp}, {TOS}

COERCIONS


from STACK
uses REG
gen move {TOS}, %a			yields %a

#ifndef NOFLOAT
from STACK
uses FREG
gen move {TOS}, %a			yields %a

from STACK
uses DFREG
gen move {TOS}, %a			yields %a
#endif

from STACK
uses REG
gen move {TOS}, %a			yields {regcon4, %a, 0}

from MEMREG				yields {memregcon4, %1, 0}

from MEMREG
uses REG
gen addr {memregrel4, %1, 0}, %a	yields %a

from REG				yields {regcon4, %1, 0}

from regcon4
gen addr {regrel4, %1.reg, %1.disp}, %1.reg
					yields %1.reg

from memregcon4
uses REG
gen addr {memregrel4, %1.reg, %1.disp}, %a
					yields %a

from LOCAL 				yields {memregrel4, fp, %1.ind}

from addr_local
uses REG
gen addr {LOCAL, %1.ind}, %a		yields %a

from src4
uses reusing %1, REG=%1			yields %a

from src4
uses reusing %1, REG=%1			yields {regcon4, %a, 0}

from memregrelcon4
uses REG
gen addr {memrel4, %1.reg, %1.disp1, %1.disp2}, %a
					yields %a

from memregrel4				yields {memregrelcon4, %1.reg,
                                                    %1.disp, 0}

from src1
uses REG
    gen movzbd %1, %a			yields %a

from src2
uses REG
    gen movzwd %1, %a			yields %a

from DLOCAL				yields {LOCAL, %1.ind+4}
					       {LOCAL, %1.ind}

from absolute8				yields {absolute4, %1.disp+4}
					       {absolute4, %1.disp}

from memrel8				yields {memrel4, %1.reg, 
					%1.disp1, %1.disp1+4}
					       {memrel4, %1.reg,
					%1.disp1, %1.disp1}

from regrel8				yields {regrel4, %1.reg, %1.disp+4}
             				       {regrel4, %1.reg, %1.disp}

from memregrel8				yields {memregrel4, %1.reg, %1.disp+4}
					       {memregrel4, %1.reg, %1.disp}

PATTERNS

/**********************************************************************
 * Group1 : load instructions                                         *
 **********************************************************************/

pat loc					yields {const4, $1}

pat ldc					leaving loc 18
						trp

pat lol					yields {LOCAL, $1}

pat loe					yields {absolute4, $1}

pat lil					yields {memrel4, fp, $1, 0}

pat lol lof				yields {memrel4, fp, $1, $2}

pat lal lof				yields {LOCAL, $1+$2}

pat lae lof				yields {absolute4, $1+$2}

pat lof
with exact MEMREG			yields {memregrel4, %1, 0}
with REG				yields {regrel4, %1, $1}
with exact addr_external		yields {absolute4, %1.disp+$1}
with exact addr_local			yields {LOCAL, %1.ind+$1}
with exact memregrel4			yields {memrel4, %1.reg,
					  %1.disp, $1}
with exact memregrelcon4		yields {memrel4, %1.reg,
					  %1.disp1, $1+%1.disp2}
with exact memregcon4			yields {memregrel4, %1.reg, %1.disp+$1}
with exact regcon4			yields {regrel4, %1.reg, %1.disp+$1}
with exact LOCAL			yields {memrel4, fp, %1.ind, $1}

pat lxl $1==0				yields fp

pat lxl $1==1				yields {LOCAL, 8}

pat lxl $1==2				yields {memrel4, fp, 8, 8}

pat lxl $1>2
    uses REG={memrel4, fp, 8, 8},
	 REG={const4, $1-2}
    gen 1:
	move {regrel4, %a, 8}, %a
	acbd {const4, 0-1}, %b, {label, "1b"}
					yields %a

pat lxa $1==0				yields {addr_local, 8}

pat lxa $1==1				yields {memregrelcon4, fp, 8, 8}

pat lxa $1==2
    uses REG={memrel4, fp, 8, 8}	yields {regcon4, %a, 8}

pat lxa $1>2
    uses REG={memrel4, fp, 8, 8},
	 REG={const4, $1-2}
    gen 1:
	move {regrel4, %a, 8}, %a
	acbd {const4, 0-1}, %b, {label, "1b"}
					yields {regcon4, %a, 8}

pat lol loi $2==1			yields {memrel1, fp, $1, 0}

pat lal loi $2==1			yields {memregrel1, fp, $1}

pat lae loi $2==1			yields {absolute1, $1}

pat lol loi $2==4			yields {memrel4, fp, $1, 0}

pat lal loi $2==4			yields {LOCAL, $1}

pat lae loi $2==4			yields {absolute4, $1}

pat lal					yields {addr_local, $1}

pat lae					yields {addr_external, $1}

pat loi	$1==1
with exact MEMREG			yields {memregrel1, %1, 0}
with REG				yields {regrel1, %1, 0}
with exact memregcon4			yields {memregrel1, %1.reg, %1.disp}
with exact regcon4			yields {regrel1, %1.reg, %1.disp}
with exact memregrel4			yields {memrel1, %1.reg, %1.disp, 0}
with exact memregrelcon4		yields {memrel1, %1.reg,
					  %1.disp1, %1.disp2}
with exact addr_local			yields {memregrel1, fp, %1.ind}
with exact addr_external		yields {absolute1, %1.disp}
with exact LOCAL			yields {memrel1, fp, %1.ind, 0}

pat loi $1==2
with exact MEMREG			yields {memregrel2, %1, 0}
with REG				yields {regrel2, %1, 0}
with exact memregcon4			yields {memregrel2, %1.reg, %1.disp}
with exact regcon4			yields {regrel2, %1.reg, %1.disp}
with exact memregrel4			yields {memrel2, %1.reg, %1.disp, 0}
with exact memregrelcon4		yields {memrel2, %1.reg,
					  %1.disp1, %1.disp2}
with exact addr_local			yields {memregrel2, fp, %1.ind}
with exact addr_external		yields {absolute2, %1.disp}
with exact LOCAL			yields {memrel2, fp, %1.ind, 0}

pat loi $1==4
with exact MEMREG			yields {memregrel4, %1, 0}
with REG				yields {regrel4, %1, 0}
with exact memregcon4			yields {memregrel4, %1.reg, %1.disp}
with exact regcon4			yields {regrel4, %1.reg, %1.disp}
with exact memregrel4			yields {memrel4,%1.reg,%1.disp,0}
with exact memregrelcon4		yields {memrel4, %1.reg,
					  %1.disp1,%1.disp2}
with exact addr_local			yields {LOCAL, %1.ind}
with exact addr_external		yields {absolute4, %1.disp}
with exact LOCAL			yields {memrel4, fp, %1.ind, 0}

pat loi $1==8
with REG				yields {regrel8, %1, 0}
with exact addr_local			yields {DLOCAL, %1.ind}
with exact addr_external		yields {absolute8, %1.disp}
with exact LOCAL			yields {memrel8, fp, %1.ind, 0}

pat loi defined($1)
with USELESS
with REG STACK
    uses REG = {const4, $1}
    gen addd %a, %1
        1:
        subd {const4, 4}, %1
        movd {regrel4, %1, 0}, {TOS}
        acbd {const4, 0-4}, %a, {label, "1b"}

pat los $1==4
with STACK
    gen jsr {absolute4, ".los"}

pat ldl					yields {DLOCAL, $1}

pat lde					yields {absolute8, $1}

pat ldf
with exact addr_local			yields {DLOCAL, %1.ind+$1}
with exact addr_external		yields {absolute8, %1.disp+$1}
with regcon4				yields {regrel8, %1.reg, 
						%1.disp+$1}

pat lpi					yields {addr_external, $1}

			
/*****************************************************************
 * Group2 : store instructions					 *
 *****************************************************************/

pat stl
with src4 + con4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen move %1, {LOCAL, $1}
with exact STACK
gen move {TOS}, {LOCAL, $1}
with exact src1
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen movzbd %1, {LOCAL, $1}
#ifndef NOFLOAT
with FREG
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen move %1, {LOCAL, $1}
#endif

pat ste
with src4 + con4
kills absolute + rel + memregrelcon4
gen move %1, {absolute4, $1}
with exact src1
kills absolute + rel + memregrelcon4
gen movzbd %1, {absolute4, $1}
#ifndef NOFLOAT
with FREG
kills absolute + rel + memregrelcon4
gen move %1, {absolute4, $1}
#endif

pat sil
with src4 + con4
kills allmincon
gen move %1, {memrel4, fp, $1, 0}
with exact src1
kills allmincon
gen movzbd %1, {memrel4, fp, $1, 0}
#ifndef NOFLOAT
with FREG
kills allmincon
gen move %1, {memrel4, fp, $1, 0}
#endif

pat stf
with exact MEMREG src4 + con4
    kills allmincon
    gen move %2, {memregrel4, %1, $1}
with REG src4 + con4
    kills allmincon
    gen move %2, {regrel4, %1, $1}
with exact memregcon4 src4 + con4
    kills allmincon
    gen move %2, {memregrel4, %1.reg, $1 + %1.disp}
with exact regcon4 consrc4
    kills allmincon
    gen move %2, {regrel4, %1.reg, $1 + %1.disp}
with exact memregrel4 consrc4
    kills allmincon
    gen move %2, {memrel4, %1.reg, %1.disp, $1}
with exact memregrelcon4 consrc4
    kills allmincon
    gen move %2, {memrel4, %1.reg, %1.disp1, %1.disp2 + $1}
with exact addr_external consrc4
    kills allmincon
    gen move %2, {absolute4, %1.disp + $1}
with exact addr_local consrc4
    kills allmincon
    gen move %2, {LOCAL,%1.ind + $1}
#ifndef NOFLOAT
with REG FREG
    kills allmincon
    gen move %2, {regrel4, %1, $1}
#endif

pat lal sti $2==4
with consrc4
    kills allmincon
    gen move %1, {LOCAL, $1}

pat lae sti $2==4
with consrc4
    kills allmincon
    gen move %1, {absolute4, $1}

pat lol sti $2==4
with consrc4
    kills allmincon
    gen move %1, {memrel4, fp, $1, 0}

pat lol sti $2==1
with src124
    kills allmincon
    gen move %1, {memrel1, fp, $1, 0}

pat sti $1 == 4
with exact MEMREG consrc4
    kills allmincon
    gen move %2, {memregrel4, %1, 0}
with REG consrc4
    kills allmincon
    gen move %2, {regrel4, %1, 0}
#ifndef NOFLOAT
with REG FREG
    kills allmincon
    gen movf %2, {regrel4, %1, 0}
#endif
with exact memregcon4 consrc4
    kills allmincon
    gen move %2, {memregrel4, %1.reg, %1.disp}
with exact regcon4 consrc4
    kills allmincon
    gen move %2, {regrel4, %1.reg, %1.disp}
with exact memregrel4 consrc4
    kills allmincon
    gen move %2, {memrel4, %1.reg, %1.disp, 0}
with exact memregrelcon4 consrc4
    kills allmincon
    gen move %2, {memrel4, %1.reg, %1.disp1, %1.disp2}
with exact addr_external consrc4
    kills allmincon
    gen move %2, {absolute4, %1.disp}
with exact addr_local consrc4
    kills allmincon
    gen move %2, {LOCAL, %1.ind}
with exact LOCAL consrc4
    kills allmincon
    gen move %2, {memrel4, fp, %1.ind, 0}

pat sti $1 == 2
with regcon4 src24
    kills allmincon
    gen move %2, {regrel2, %1.reg, %1.disp}
with exact addr_external src24
    kills allmincon
    gen move %2, {absolute2, %1.disp}
with exact addr_local src24
    kills allmincon
    gen move %2, {memregrel2, fp, %1.ind}

pat sti $1 == 1
with exact MEMREG src124
    kills allmincon
    gen move %2, {memregrel1, %1, 0}
with REG src124
    kills allmincon
    gen move %2, {regrel1, %1, 0}
with exact memregcon4 src124
    kills allmincon
    gen move %2, {memregrel1, %1.reg, %1.disp}
with exact regcon4 src124
    kills allmincon
    gen move %2, {regrel1, %1.reg, %1.disp}
with exact memregrel4 src124
    kills allmincon
    gen move %2, {memrel1, %1.reg, %1.disp, 0}
with exact memregrelcon4 src124
    kills allmincon
    gen move %2, {memrel1, %1.reg, %1.disp1, %1.disp2}
with exact addr_external src124
    kills allmincon
    gen move %2, {absolute1, %1.disp}
with exact addr_local src124
    kills allmincon
    gen move %2, {memregrel1, fp, %1.ind}
with exact LOCAL src124
    kills allmincon
    gen move %2, {memrel1, fp, %1.ind, 0}

pat sti $1==8
#ifndef NOFLOAT
with regcon4 DFREG
    kills allmincon
    gen move %2, {regrel8, %1.reg, %1.disp}
with exact addr_external DFREG
    kills allmincon
    gen move %2, {absolute8, %1.disp}
with exact addr_local DFREG
    kills allmincon
    gen move %2, {memregrel8, fp, %1.ind}
#endif
with regcon4 consrc4 consrc4
    kills allmincon
    gen move %1, {regrel4, %1.reg, %1.disp}
	move %2, {regrel4, %1.reg, %1.disp+4}

pat sti defined($1)
with USELESS
with REG STACK
    uses REG={const4, $1}
    gen 1:
	movd {TOS}, {regrel4, %1, 0}
	addr {regrel4, %1, 4}, %1
	acbd {const4, 0-4}, %a, {label, "1b"}

pat sts
with STACK
    gen jsr {absolute4, ".sts"}

pat sdl
with consrc4 consrc4
kills rel, LOCAL %ind-8 < $1 && %ind+8 > $1
gen move %1, {LOCAL, $1}
    move %2, {LOCAL, $1+4}
#ifndef NOFLOAT
with DFREG
kills rel, LOCAL %ind-8 < $1 && %ind+8 > $1
gen move %1, {DLOCAL, $1}
#endif

pat sde
with consrc4 consrc4
kills absolute + rel + memregrelcon4
gen move %1, {absolute4, $1}
    move %2, {absolute4, $1+4}
#ifndef NOFLOAT
with DFREG
kills absolute + rel + memregrelcon4
gen move %1, {absolute8, $1}
#endif

pat sdf
with exact addr_local consrc4 consrc4
    kills allmincon
    gen move %2, {LOCAL, %1.ind+$1}
	move %3, {LOCAL, %1.ind+4+$1}
with exact addr_external consrc4 consrc4
    kills allmincon
    gen move %2, {absolute4, %1.disp+$1}
	move %3, {absolute4, %1.disp+4+$1}
with  regcon4 consrc4 consrc4
    kills allmincon
    gen move %2, {regrel4, %1.reg, %1.disp+$1}
        move %3, {regrel4, %1.reg, %1.disp+$1+4}
#ifndef NOFLOAT
with exact addr_local DFREG
    kills allmincon
    gen move %2, {DLOCAL, %1.ind+$1}
with exact addr_external DFREG
    kills allmincon
    gen move %2, {absolute8, %1.disp+$1}
with exact regcon4 DFREG
    kills allmincon
    gen move %2, {regrel8, %1.reg, %1.disp+$1}
#endif

/*****************************************************************
 * Group3 : integer arithmetic					 *
 *****************************************************************/
pat loe loc adi ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen addd {const4, $2}, {absolute4, $1}

pat lol loc adi stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd {const4, $2}, {LOCAL, $1}

pat lil loc adi sil $3==4 && $1==$4
kills allmincon
gen addd {const4, $2}, {memrel4, fp, $1, 0}

pat lol adi stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd %1, {LOCAL, $1}

pat lil adi sil $1==$3 && $2==4
with src4
kills allmincon
gen addd %1, {memrel4, fp, $1, 0}

pat loe adi ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen addd %1, {absolute4, $1}

pat adi $1 == 4
with exact MEMREG const4		yields {memregcon4, %1, %2.num}
with exact REG const4		yields {regcon4, %1, %2.num}
with exact const4 REG 		yields {regcon4, %2, %1.num}
with exact memregrel4 const4		yields {memregrelcon4, %1.reg,
					%1.disp, %2.num}
with exact memregcon4 const4		yields {memregcon4, %1.reg,
					%1.disp + %2.num}
with exact regcon4 const4		yields {regcon4, %1.reg,
					%1.disp + %2.num}
with exact memregrelcon4 const4		yields {memregrelcon4, %1.reg,
					%1.disp1, %1.disp2+%2.num}
with exact addr_local const4		yields {addr_local, %1.ind+%2.num}
with exact LOCAL const4			yields {memregrelcon4, fp,
					%1.ind, %2.num}
with exact const4 LOCAL 		yields {memregrelcon4, fp,
					%2.ind, %1.num}
with exact const4 addr_local		yields {addr_local, %2.ind+%1.num}
with exact MEMREG addr_external		yields {memregcon4, %1, %2.disp}
with exact REG addr_external		yields {regcon4, %1, %2.disp}
with exact memregrel4 addr_external	yields {memregrelcon4, %1.reg,
					%1.disp, %2.disp}
with exact memregcon4 addr_external	yields {memregcon4, %1.reg,
					%1.disp + %2.disp}
with exact regcon4 addr_external	yields {regcon4, %1.reg,
					%1.disp + %2.disp}
with exact memregrelcon4 addr_external	yields {memregrelcon4, %1.reg,
					%1.disp1, %1.disp2+%2.disp}
with src4 REG
    gen addd %1, %2			yields %2
with REG src4
    gen addd %2, %1			yields %1

pat loe loc sbi ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen addd {const4, 0-$2}, {absolute4, $1}

pat lol loc sbi stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd {const4, 0-$2}, {LOCAL, $1}

pat lil loc sbi sil $3==4 && $1==$4
kills allmincon
gen addd {const4, 0-$2}, {memrel4, fp, $1, 0}

pat sbi $1 == 4
with src4 REG
    gen subd %1, %2			yields %2
with const4 REG
    gen addd {const4, 0-%1.num}, %2	yields %2
with exact addr_local addr_local
    uses REG={const4, %2.ind}
    gen subd {const4, %1.ind}, %a	yields %a

pat mli $1 == 4
with src4 REG
    gen muld %1, %2			yields %2
with REG src4
    gen muld %2, %1			yields %1

pat dvi $1 == 4
with src4 REG
    gen quod %1,%2			yields %2

pat rmi $1 == 4
with src4 REG
    gen remd %1, %2			yields %2

pat ngi $1 == 4
with src4
    uses reusing %1, REG
    gen negd %1, %a			yields %a

pat lol ngi stl $1==$3 && $2==4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen negd {LOCAL, $1}, {LOCAL, $1}

pat loe ngi ste $1==$3 && $2==4
kills absolute + rel + memregrelcon4
    gen negd {absolute4, $1}, {absolute4, $1}

pat lil ngi sil $1==$3 && $2==4
kills allmincon
    gen negd {memrel4, fp, $1, 0}, {memrel4, fp, $1, 0}

pat sli $1 == 4
with src124 REG
    gen ashd %1, %2			yields %2

pat lol loc sli stl $1==$4 && $3==4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen ashd {const4, $2}, {LOCAL, $1}

pat loe loc sli ste $1==$4 && $3==4
kills absolute + rel + memregrelcon4
    gen ashd {const4, $2}, {absolute4, $1}

pat loc sri $2 == 4
with USELESS
with REG
    gen ashd {const4,0-$1}, %1		yields %1

pat sri $1 == 4
with USELESS
with REG REG
gen negd %1, %1
    ashd %1, %2				yields %2

pat lol loc sri stl $1==$4 && $3==4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen ashd {const4, 0-$2}, {LOCAL, $1}

pat loe loc sri ste $1==$4 && $3==4
kills absolute + rel + memregrelcon4
    gen ashd {const4, 0-$2}, {absolute4, $1}


/*****************************************************************
 * Group4 : unsigned arithmetic					 *
 *****************************************************************/

pat loe loc adu ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen addd {const4, $2}, {absolute4, $1}

pat lol loc adu stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd {const4, $2}, {LOCAL, $1}

pat lil loc adu sil $3==4 && $1==$4
kills allmincon
gen addd {const4, $2}, {memrel4, fp, $1, 0}

pat lol adu stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd %1, {LOCAL, $1}

pat lil adu sil $1==$3 && $2==4
with src4
kills allmincon
gen addd %1, {memrel4, fp, $1, 0}

pat loe adu ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen addd %1, {absolute4, $1}

pat adu						leaving adi $1

pat loe loc sbu ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen addd {const4, 0-$2}, {absolute4, $1}

pat lol loc sbu stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd {const4, 0-$2}, {LOCAL, $1}

pat lil loc sbu sil $3==4 && $1==$4
kills allmincon
gen addd {const4, 0-$2}, {memrel4, fp, $1, 0}

pat sbu						leaving sbi $1

pat mlu $1 == 4
with src4 src4
    uses reusing %1, REGPAIR
    gen move %1, %a.1
        meid %2, %a			yields %a.1
 
pat dvu $1 == 4
with STACK
    gen jsr {absolute4, ".dvu"}		yields r0

pat rmu $1 == 4
with STACK
    gen jsr {absolute4, ".rmu"}		yields r0

pat slu						leaving sli $1

pat loc sru $2 == 4
with USELESS
with REG
    gen lshd {const4, 0-$1}, %1		yields %1

pat sru $1 == 4
with USELESS
with REG REG
    gen negd %1, %1
        lshd %1, %2			yields %2


/*****************************************************************
 * Group5 : floating point arithmetic				 *
 *****************************************************************/

#ifndef NOFLOAT
pat adf $1==4
with fsrc4 FREG
    gen addf %1, %2			yields %2

pat adf $1==8
with fsrc8 DFREG
    gen addl %1, %2			yields %2

pat sbf $1==4
with fsrc4 FREG
    gen subf %1, %2			yields %2

pat sbf $1==8
with fsrc8 DFREG
    gen subl %1, %2			yields %2

pat mlf $1==4
with fsrc4 FREG
    gen mulf %1, %2			yields %2

pat mlf $1==8
with fsrc8 DFREG
    gen mull %1, %2			yields %2

pat dvf $1==4
with fsrc4 FREG
    gen divf %1, %2			yields %2

pat dvf $1==8
with fsrc8 DFREG
    gen divl %1, %2			yields %2

pat ngf $1==4
with FREG
    gen negf %1, %1			yields %1

pat ngf $1==8
with DFREG
    gen negl %1, %1			yields %1

pat fif $1==4
with fsrc4 FREG
uses FREG, REG
    gen mulf %1, %2
	truncfd %2, %b
	movdf %b, %a
	subf %a, %2			yields %a %2

pat fif $1==8
with fsrc8 DFREG
uses DFREG, REG
    gen mull %1, %2
	truncld %2, %b
	movdl %b, %a
	subl %a, %2			yields %a %2

pat fef $1==4
with FREG
uses REG
    gen movf %1, {TOS}
	movf %1, {TOS}
	lshd {const4, 1}, {TOS}
	lshd {const4, 0-24}, {TOS}
	movd {TOS}, %a
	subd {const4, 127}, %a
	ord {const4, 0x3F000000}, {TOS}
	lshd {const4,2},{TOS}
	lshd {const4,0-2},{TOS}
	cbitd {const4, 23},{TOS}
	movf {TOS}, %1			yields %1 %a

pat fef $1==8
with DFREG
uses REG
    gen movl %1, {TOS}
	movl %1, {TOS}
	adjspd {const4, 0-4}
	lshd {const4, 1}, {TOS}
	lshd {const4, 0-21}, {TOS}
	movd {TOS}, %a
	subd {const4, 1023}, %a
	ord {const4, 0x3FE00000}, {memregrel4, sp, 4}
	lshd {const4,2},{memregrel4, sp, 4}
	lshd {const4,0-2},{memregrel4, sp, 4}
	cbitd {const4, 52},{TOS}
	movl {TOS}, %1			yields %1 %a

#else

pat adf					leaving loc 18 trp
pat sbf					leaving loc 18 trp
pat mlf					leaving loc 18 trp
pat dvf					leaving loc 18 trp
pat ngf					leaving loc 18 trp
pat fif					leaving loc 18 trp
pat fef					leaving loc 18 trp

#endif

/*****************************************************************
 * Group6 : pointer arithmetic					 *
 *****************************************************************/

pat lol lol adp stl $1==$2 && $2==$4
kills allmincon
uses REG={LOCAL, $1}
gen addr {memrel4, fp, $1, $3}, {LOCAL, $1}	yields %a

pat loe loe adp ste $1==$2 && $2==$4
kills allmincon
uses REG={absolute4, $1}
gen addd {const4, $3}, {absolute4, $1}

pat lol adp stl $1==$3
kills allmincon
gen addr {memrel4, fp, $1, $2}, {LOCAL, $1}

pat loe adp ste $1==$3
kills allmincon
gen addd {const4, $2}, {absolute4, $1}

pat adp
with exact MEMREG			yields {memregcon4, %1, $1}
with REG				yields {regcon4, %1, $1}
with exact memregcon4			yields {memregcon4, %1.reg,
					%1.disp + $1}
with exact regcon4			yields {regcon4, %1.reg,
					%1.disp + $1}
with exact memregrel4			yields {memregrelcon4, %1.reg,
					%1.disp, $1}
with exact memregrelcon4		yields {memregrelcon4, %1.reg,
					%1.disp1, %1.disp2 + $1}
with exact addr_external		yields {addr_external, $1+%1.disp}
with exact addr_local			yields {addr_local, %1.ind + $1}
with exact LOCAL			yields {memregrelcon4, fp, 
					%1.ind, $1}

pat loe loc ads ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen addd {const4, $2}, {absolute4, $1}

pat lol loc ads stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd {const4, $2}, {LOCAL, $1}

pat lol ads stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen addd %1, {LOCAL, $1}

pat loe ads ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen addd %1, {absolute4, $1}

pat ads $1==4					leaving adi 4

pat sbs $1==4					leaving sbi 4

/*****************************************************************
 * Group7 : increment/decrement/zero 				 *
 *****************************************************************/

pat inc
with USELESS
with REG
    gen addd {const4,1}, %1		yields %1
with exact STACK
    gen addd {const4, 1},{TOS}

pat loc inc				yields {const4, $1+1}

pat lol inc stl $1==$3
kills allmincon
gen addd {const4, 1}, {LOCAL, $1}

pat lol dec stl $1==$3
kills allmincon
gen addd {const4, 0-1}, {LOCAL, $1}

pat lil inc sil $1==$3
kills allmincon
gen addd {const4, 1}, {memrel4, fp, $1, 0}

pat lil dec sil $1==$3
kills allmincon
gen addd {const4, 0-1}, {memrel4, fp, $1, 0}

pat inl
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen addd {const4,1},{LOCAL, $1}

pat ine
kills absolute, rel, memregrelcon4
    gen addd {const4,1},{absolute4, $1}

pat dec
with USELESS
with  REG
    gen addd {const4,0-1}, %1		yields %1
with exact STACK
    gen addd {const4,0-1}, {TOS}

pat loc dec				yields {const4, $1-1}

pat del
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen addd {const4,0-1},{LOCAL, $1}

pat dee
kills absolute, rel, memregrelcon4
    gen addd {const4,0-1},{absolute4, $1}

pat zrl
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
    gen move {const4, 0}, {LOCAL, $1}

pat zre
kills absolute, rel, memregrelcon4
    gen move {const4, 0}, {absolute4, $1}

#ifndef NOFLOAT
pat zrf $1==4
with STACK
gen movd {const4, 0}, {TOS}

pat zrf $1==8
with STACK
gen movd {const4, 0}, {TOS}
    movd {const4, 0}, {TOS}
#else
pat zrf					leaving loc 18 trp
#endif

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

pat zer $1==8				yields {const4, 0}
					       {const4, 0}

pat zer $1==12				yields {const4, 0}
			                       {const4, 0}
					       {const4, 0}

pat zer $1>12
with STACK
    uses REG={const4, $1/4}
    gen 1:
	movqd {const4, 0}, {TOS}
	acbd {const4, 0-1}, %a, {label, "1b"}

/*****************************************************************
 * Group8 : convert 						 *
 *****************************************************************/

pat loc loc cii $1==4 && $2==4

pat loc loc cii $1==1 && $2==4
with src124
uses reusing %1, REG
    gen movxbd %1, %a				yields %a

pat loc loc cii $1==2 && $2==4
with src24
uses reusing %1, REG
    gen movxwd %1, %a				yields %a

pat cii
with STACK
    gen jsr {absolute4, ".cii"}

pat cui
with src4 src4

#ifndef NOFLOAT
pat loc loc cfi $1==8 && $2==4
with fsrc8
uses REG
    gen roundld %1, %a				yields %a

pat loc loc cfi $1==4 && $2==4
with fsrc4
uses REG
    gen roundfd %1, %a				yields %a

pat cfi
with STACK
    gen jsr {absolute4, ".cfi"}

pat loc loc cif $1==4 && $2==8
with src4
uses DFREG
    gen movdl %1, %a				yields %a

pat loc loc cif $1==4 && $2==4
with src4
uses FREG
    gen movdf %1, %a				yields %a

pat cif
with STACK
    gen jsr {absolute4, ".cif"}

pat cuf
					leaving loc 18 trp

pat loc loc cff $1==4 && $2==4

pat loc loc cff $1==8 && $2==8

pat loc loc cff $1==4 && $2==8
with fsrc4
uses DFREG
    gen movfl %1, %a				yields %a

pat loc loc cff $1==8 && $2==4
with fsrc8
uses FREG
    gen movlf %1, %a				yields %a

pat cff
with STACK
    gen jsr {absolute4, ".cff"}
 
#else

pat cif					leaving loc 18 trp
pat cfi					leaving loc 18 trp
pat cuf					leaving loc 18 trp
pat cfu					leaving loc 18 trp
pat cff					leaving loc 18 trp

#endif
pat ciu
with src4 src4

pat cuu
with src4 src4

pat cfu
					leaving loc 18 trp

/*****************************************************************
 * Group9 : logical 						 *
 *****************************************************************/

pat loe loc and ste $3==4 && $1==$4
kills absolute + rel + memregrelcon4
gen andd {const4, $2}, {absolute4, $1}

pat lol loc and stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen andd {const4, $2}, {LOCAL, $1}

pat lil loc and sil $3==4 && $1==$4
kills allmincon
gen andd {const4, $2}, {memrel4, fp, $1, 0}

pat lol and stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen andd %1, {LOCAL, $1}

pat lil and sil $1==$3 && $2==4
with src4
kills allmincon
gen andd %1, {memrel4, fp, $1, 0}

pat loe and ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen andd %1, {absolute4, $1}

pat and $1==4
with src4 REG
    gen andd %1, %2				yields %2
with REG src4
    gen andd %2, %1				yields %1

pat and $1>4
with STACK
    gen move {const4, $1}, r0
        addr {memregrel4, sp, $1}, r1
	1:
	andd {TOS}, {regrel4, r1, 0}
	addr {regrel4, r1, 4}, r1
	acbd {const4, 0-4}, r0, {label, "1b"}

pat lol ior stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen ord %1, {LOCAL, $1}

pat lol loc ior stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen ord {const4, $2}, {LOCAL, $1}

pat lil loc ior sil $3==4 && $1==$4
kills allmincon
gen ord {const4, $2}, {memrel4, fp, $1, 0}

pat lil ior sil $1==$3 && $2==4
with src4
kills allmincon
gen ord %1, {memrel4, fp, $1, 0}

pat loe ior ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen ord %1, {absolute4, $1}

pat lol loc xor stl $3==4 && $1==$4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen xord {const4, $2}, {LOCAL, $1}

pat lil loc xor sil $3==4 && $1==$4
kills allmincon
gen xord {const4, $2}, {memrel4, fp, $1, 0}

pat lol xor stl $1==$3 && $2==4
with src4
kills rel, LOCAL %ind-4 < $1 && %ind+4 > $1
gen xord %1, {LOCAL, $1}

pat lil xor sil $1==$3 && $2==4
with src4
kills allmincon
gen xord %1, {memrel4, fp, $1, 0}

pat loe xor ste $1==$3 && $2==4
with src4
kills absolute + rel + memregrelcon4
gen xord %1, {absolute4, $1}

pat ior $1==4
with src4 REG
    gen ord %1, %2				yields %2
with REG src4
    gen ord %2, %1				yields %1

pat ior $1>4
with STACK
    gen move {const4, $1}, r0
        addr {memregrel4, sp, $1}, r1
	1:
	ord {TOS}, {regrel4, r1, 0}
	addr {regrel4, r1, 4}, r1
	acbd {const4, 0-4}, r0, {label, "1b"}

pat xor $1==4
with src4 REG
    gen xord %1, %2				yields %2
with REG src4
    gen xord %2, %1				yields %1

pat xor $1>4
with STACK
    gen move {const4, $1}, r0
        addr {memregrel4, sp, $1}, r1
	1:
	xord {TOS}, {regrel4, r1, 0}
	addr {regrel4, r1, 4}, r1
	acbd {const4, 0-4}, r0, {label, "1b"}

pat com $1==4
with USELESS
with REG
    gen comd %1, %1				yields %1

pat com $1>4
with STACK
    gen move {const4, $1}, r0
	addr {memregrel4, sp, 0}, r1
	1:
	comd {regrel4, r1, 0}, {regrel4, r1, 0}
	addr {regrel4, r1, 4}, r1
	acbd {const4, 0-4}, r0, {label, "1b"}

pat rol $1 == 4
with src124 REG
    gen rotd %1, %2			yields %2

pat loc ror $2 == 4
with USELESS
with REG
    gen rotd {const4, 0-$1}, %1		yields %1

pat ror $1 == 4
with USELESS
with REG REG
    gen negd %1, %1
	rotd %1, %2			yields %2

/*****************************************************************
 * Group10 : sets 						 *
 *****************************************************************/

pat inn zeq $1==4
with src4 REG
    gen cmpd {const4, 0}, %1
	bgt {label, $2}
	tbitd %1, %2
	bfc {label, $2}

pat inn zne $1==4
with src4 REG
    gen cmpd {const4, 0}, %1
	bgt {label, "1f"}
	tbitd %1, %2
	bfs {label, $2}
	1:

pat inn $1==4
with src4 REG
    uses REG
    gen	tbitd %1, %2
	sfsd %a				
        cmpd {const4,0}, %1
	ble {label, "1f"}
	xord %a, %a	
	1:					yields %a

pat inn $1>4
with src4 STACK
    uses REG
    gen tbitd %1, {TOS}
	adjspd {const4, 0-4}
        sfsd %a
        cmpd {const4,0}, %1
	ble {label, "1f"}
	xord %a, %a	
	1:					yields %a

pat inn !defined($1)
with src4 src4 STACK
    uses REG
    gen tbitd %2, {TOS}
	adjspd {const4, 0-4}
        sfsd %a
        cmpd {const4,0}, %2
	ble {label, "1f"}
	xord %a, %a	
	1:					yields %a

pat set $1==4
with src4
    uses REG={const4, 0}
    gen sbitd %1, %a			yields %a

pat set $1>4
with src4 STACK
    uses REG={const4, $1/4}
    gen 1:
	movqd {const4, 0}, {TOS}
	acbd {const4, 0-1}, %a, {label, "1b"}
	sbitd %1, {TOS}

pat set !defined($1)
with src4 src4 STACK
    uses reusing %1, REG=%1
    gen quod {const4, 4}, %a
	1:
	movqd {const4, 0}, {TOS}
	acbd {const4, 0-1}, %a, {label, "1b"}
	sbitd %2, {TOS}

/*****************************************************************
 * Group11 : array 						 *
 *****************************************************************/

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 USELESS
with REG
    gen ashd {const4, 1}, %1		yields %1
					leaving adi 2

pat lae aar $2==2 && rom($1,3)==2 && rom($1,1)!=0 
with USELESS
with REG
    gen ashd {const4, 1}, %1		yields {regcon4, %1,(0-2)*rom($1,1)}
					leaving adi 2

pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)==0
with USELESS
with REG addr_local
uses REG
    gen addr {memregrelsid, %2.ind, fp, %1}, %a	
					yields %a
with REG addr_external
uses REG
    gen addr {abssid, %2.disp, %1}, %a	
					yields %a
with					leaving lae $1 aar $2

pat lae aar $2==4 && rom($1,3)==4 && rom($1,1)!=0
with USELESS
with REG addr_local
uses REG
    gen subd {const4, rom($1,1)}, %1
        addr {memregrelsid, %2.ind, fp, %1}, %a	
					yields %a
with REG addr_external
uses REG
    gen subd {const4, rom($1,1)}, %1
        addr {abssid, %2.disp, %1}, %a	
					yields %a
with 					leaving lae $1 aar $2

pat lae lar $2==4 && rom($1,3)==4 && rom($1,1)==0
with USELESS
with REG addr_local		yields {memregrelsid, %2.ind, fp, %1}
with REG addr_external		yields {abssid, %2.disp, %1}
with 					leaving lae $1 lar $2

pat lae lar $2==4 && rom($1,3)==4 && rom($1,1)!=0
with USELESS
with REG addr_local
    gen subd {const4, rom($1,1)}, %1
				yields {memregrelsid, %2.ind, fp, %1}
with REG addr_external
    gen subd {const4, rom($1,1)}, %1
				yields {abssid, %2.disp, %1}
with 					leaving lae $1 lar $2

pat lae sar $2==4 && rom($1,3)==4 && rom($1,1)==0
with src4 REG addr_local
kills allmincon
    gen move %1, {memregrelsid, %3.ind, fp, %2}
with src4 REG addr_external
kills allmincon
    gen move %1, {abssid, %3.disp, %2}
with					leaving lae $1 sar $2

pat lae lar $2==4 && rom($1,3)==4 && rom($1,1)!=0
with src4 REG addr_local
kills allmincon
    gen subd {const4, rom($1,1)}, %2
	move %1, {memregrelsid, %3.ind, fp, %2}
with src4 REG addr_external
kills allmincon
    gen subd {const4, rom($1,1)}, %2
	move %1, {abssid, %3.disp, %2}
with					leaving lae $1 sar $2

pat lae aar $2==4 && rom($1,1)==0
with src4 REG
    gen indexd %2, {const4, rom($1,3)-1}, %1	yields %2

pat lae aar $2==4 && rom($1,1)!=0
with USELESS
with REG REG
    gen subd {const4,rom($1,1)}, %1
	indexd %2, {const4, rom($1,3)-1}, %1	yields %2

pat lae sar defined(rom($1,3))
				leaving	lae $1
					aar $2
					sti rom($1,3)

pat lae lar defined(rom($1,3))
				leaving lae $1
					aar $2
					loi rom($1,3)

pat aar defined($1)
with STACK
gen jsr {absolute4, ".aar"}

pat lar defined($1)
with STACK
gen jsr {absolute4, ".lar"}

pat sar defined($1)
with STACK
gen jsr {absolute4, ".sar"}

pat aar !defined($1)
with src4 STACK
gen jsr {absolute4, ".aar"}

pat lar !defined($1)
with src4 STACK
gen jsr {absolute4, ".lar"}

pat sar !defined($1)
with src4 STACK
gen jsr {absolute4, ".sar"}

/*****************************************************************
 * Group12 : compare 						 *
 *****************************************************************/

proc cmitxxand
with src4 src4 REG
gen cmpd %2, %1
    brxx* {label, "1f"}
    xord %3, %3
    1:

proc cmitxxior
with src4 src4 REG
gen cmpd %2, %1
    brxx* {label, "1f"}
    sbitd {const4, 0}, %3
    1:

proc txxand
with src4 REG
gen cmpd {const4, 0}, %1
    brxx* {label, "1f"}
    xord %2, %2
    1:

proc txxior
with src4 REG
gen cmpd {const4, 0}, %1
    brxx* {label, "1f"}
    sbitd {const4, 0}, %2
    1:

pat cmi tlt and $1==4 && $3==4	call cmitxxand("blt")
pat cmi tle and $1==4 && $3==4	call cmitxxand("ble")
pat cmi teq and $1==4 && $3==4	call cmitxxand("beq")
pat cmi tne and $1==4 && $3==4	call cmitxxand("bne")
pat cmi tge and $1==4 && $3==4	call cmitxxand("bge")
pat cmi tgt and $1==4 && $3==4	call cmitxxand("bgt")

pat cmi tlt ior $1==4 && $3==4	call cmitxxior("blt")
pat cmi tle ior $1==4 && $3==4	call cmitxxior("ble")
pat cmi teq ior $1==4 && $3==4	call cmitxxior("beq")
pat cmi tne ior $1==4 && $3==4	call cmitxxior("bne")
pat cmi tge ior $1==4 && $3==4	call cmitxxior("bge")
pat cmi tgt ior $1==4 && $3==4	call cmitxxior("bgt")

pat tlt and $2==4		call txxand("bgt")
pat tle and $2==4		call txxand("bge")
pat teq and $2==4		call txxand("beq")
pat tne and $2==4		call txxand("bne")
pat tge and $2==4		call txxand("ble")
pat tgt and $2==4		call txxand("blt")

pat tlt ior $2==4		call txxior("bgt")
pat tle ior $2==4		call txxior("bge")
pat teq ior $2==4		call txxior("beq")
pat tne ior $2==4		call txxior("bne")
pat tge ior $2==4		call txxior("ble")
pat tgt ior $2==4		call txxior("blt")

pat cmi $1==4
with src4 REG
    gen subd %1, %2			yields %2

#ifndef NOFLOAT
pat cmf $1==4
with fsrc4 fsrc4
uses REG = {const4, 0}
    gen cmpf %1, %2
	beq {label, "1f"}
	bgt {label, "2f"}
	movd {const4, 1}, %a
	br {label, "1f"}
	2:
	movd {const4, 0-1}, %a
	1:				yields %a

pat cmf $1==8
with fsrc8 fsrc8
uses REG = {const4, 0}
    gen cmpl %1, %2
	beq {label, "1f"}
	bgt {label, "2f"}
	movd {const4, 1}, %a
	br {label, "1f"}
	2:
	movd {const4, 0-1}, %a
	1:				yields %a

#else

pat cmf					leaving loc 18 trp

#endif
pat cmu $1==4
with src4 src4
    uses REG={const4, 0}
    gen cmpd %2, %1
	blo {label, "1f"}
	shid %a
	br {label, "2f"}
	1:
	addd {const4, 0-1}, %a
	2:				yields %a

pat cmu defined($1)
with STACK
    gen move {const4, $1}, {TOS}
	jsr {absolute4, ".cmu"}		yields r1

pat cms $1==4				leaving cmi $1

pat cms $1!=4
with STACK
gen move {const4, $1}, {TOS}
    jsr {absolute4, ".cms"}		yields r1

pat cms !defined($1)
with STACK
gen jsr {absolute4, ".cms"}		yields r1

pat cmp
with exact addr_local addr_local	yields {const4, %2.ind}
					       {const4, %1.ind}
					leaving sbi 4
with					leaving cmu 4

proc txx
with src4
    uses REG
    gen cmpqd {const4, 0}, %1
	sxx* %a					yields %a

pat tlt	       			call txx("sgtd")
pat tle	       			call txx("sged")
pat teq	       			call txx("seqd")
pat tne	       			call txx("sned")
pat tge	       			call txx("sled")
pat tgt	       			call txx("sltd")

/*****************************************************************
 * Group13 : branch 						 *
 *****************************************************************/

proc bxx example beq
with src4 src4 STACK
	gen cmpd %2, %1
	    brxx* {label, $1}
with exact src4 STACK
    gen cmpd {TOS}, %1
	brxx* {label, $1}

pat blt				call bxx("blt")
pat ble				call bxx("ble")
pat beq				call bxx("beq")
pat bne				call bxx("bne")
pat bge				call bxx("bge")
pat bgt				call bxx("bgt")

pat bra
with STACK
    gen br {label, $1}

pat loc beq $1>=0 && $1<=127
with exact src1
kills ALL
gen cmpb {const4, $1}, %1
    beq {label, $2}
with					yields {const4, $1}
					leaving beq $2

pat loc bne $1>=0 && $1<=127
with exact src1
kills ALL
gen cmpb {const4, $1}, %1
    bne {label, $2}
with					yields {const4, $1}
					leaving bne $2

proc cmpzxx example cmp zeq
with src4 src4 STACK
    gen cmpd %2,%1
	brxx* {label, $2}
with exact src4 STACK
    gen cmpd {TOS}, %1
	brxx* {label, $2}
with exact addr_local addr_local
    kills ALL
    gen cmpd {const4, %2.ind}, {const4, %1.ind}
	brxx* {label, $2}

pat cmp zlt			call cmpzxx("blo")
pat cmp zle			call cmpzxx("bls")
pat cmp zeq			call cmpzxx("beq")
pat cmp zne			call cmpzxx("bne")
pat cmp zge			call cmpzxx("bhs")
pat cmp zgt			call cmpzxx("bhi")

#ifndef NOFLOAT
proc cmf4zxx example cmf zeq
with fsrc4 fsrc4 STACK
    gen cmpf %2,%1
	brxx* {label, $2}
with exact fsrc4 STACK
    gen cmpf {TOS}, %1
	brxx* {label, $2}

pat cmf zlt $1==4			call cmf4zxx("blo")
pat cmf zle $1==4			call cmf4zxx("bls")
pat cmf zeq $1==4			call cmf4zxx("beq")
pat cmf zne $1==4			call cmf4zxx("bne")
pat cmf zge $1==4			call cmf4zxx("bhs")
pat cmf zgt $1==4			call cmf4zxx("bhi")

proc cmf8zxx example cmf zeq
with fsrc8 fsrc8 STACK
    gen cmpl %2,%1
	brxx* {label, $2}
with exact fsrc8 STACK
    gen cmpl {TOS}, %1
	brxx* {label, $2}

pat cmf zlt $1==8			call cmf8zxx("blo")
pat cmf zle $1==8			call cmf8zxx("bls")
pat cmf zeq $1==8			call cmf8zxx("beq")
pat cmf zne $1==8			call cmf8zxx("bne")
pat cmf zge $1==8			call cmf8zxx("bhs")
pat cmf zgt $1==8			call cmf8zxx("bhi")
#endif

proc zxx example zeq
with src4 STACK
    gen cmpqd {const4,0}, %1
	brxx* {label, $1}
with exact STACK
    gen cmpqd {const4,0}, {TOS}
	brxx* {label, $1}

pat zlt				call zxx("bgt")
pat zle				call zxx("bge")
pat zeq				call zxx("beq")
pat zne				call zxx("bne")
pat zge				call zxx("ble")
pat zgt				call zxx("blt")

/*****************************************************************
 * Group14 : procedure call 					 *
 *****************************************************************/

pat cal
with STACK
    gen jsr {absolute4, $1}

pat cai
with USELESS
with REG STACK
    gen jsr %1

pat ret $1==0
with STACK
    gen exit {label, "[]"}
	ret {const4, 0}

pat ret $1==4
with src4 STACK
    gen move %1, r0
	exit {label, "[]"}
	ret {const4, 0}

pat ret $1==8
with STACK
    gen move {TOS}, r0
	move {TOS}, r1
	exit {label, "[]"}
	ret {const4, 0}

pat lfr $1==4				yields r0

pat lfr $1==8				yields r1 r0

/*****************************************************************
 * Group15 : miscellaneous 					 *
 *****************************************************************/

pat asp
with STACK
    gen adjspd {const4,0-$1}

pat ass $1==4
with USELESS
with REG STACK
    gen negd %1, %1
	adjspd %1
with const4 STACK
    gen adjspd {const4,0-%1.num}

pat blm $1==0

pat blm $1==4
with USELESS
with REG REG
kills allmincon
    gen move {regrel4, %2, 0}, {regrel4, %1, 0}

pat blm $1>4 && $1<=16
with USELESS
with REG REG
kills allmincon
    gen movmd %2, %1, {const4, $1}
with exact addr_external addr_external
kills allmincon
    gen movmd {absolute4, %2.disp}, {absolute4, %1.disp}, {const4, $1}
with exact addr_external addr_local
kills allmincon
    gen movmd {LOCAL, %2.ind}, {absolute4, %1.disp}, {const4, $1}
with exact addr_local addr_external
kills allmincon
    gen movmd {absolute4, %2.disp}, {LOCAL, %1.ind}, {const4, $1}
with exact addr_local addr_local
kills allmincon
    gen movmd {LOCAL, %2.ind}, {LOCAL, %1.ind}, {const4, $1}

pat blm $1>16
with USELESS
with REG REG
kills allmincon
    uses REG={const4,$1}
    gen 1:
	movd {regrel4, %2, 0}, {regrel4, %1, 0}
	addr {regrel4, %1, 4}, %1
	addr {regrel4, %2, 4}, %2
	acbd {const4, 0-4}, %a, {label, "1b"}

pat bls $1==4
with USELESS
with REG
kills ALL
    gen 1:
	movd {memrel4, sp, 4, 0}, {memrel4, sp, 0, 0}
	addr {memrel4, sp, 0, 4}, {memregrel4, sp, 0}
	addr {memrel4, sp, 4, 4}, {memregrel4, sp, 4}
	acbd {const4, 0-4}, %1, {label, "1b"}
	adjspd {const4, 0-8}

pat lae csa $2==4
with src4 STACK
    gen move %1, r0
	move {addr_external, $1}, r1
	jsr {absolute4, ".csa"}

pat csa
with STACK
    gen movd {TOS}, r1
	movd {TOS}, r0
	jsr {absolute4, ".csa"}

pat lae csb $2==4
with src4 STACK
    gen move %1, r0
	move {addr_external, $1}, r1
	jsr {absolute4, ".csb"}

pat csb
with STACK
    gen movd {TOS}, r1
	movd {TOS}, r0
	jsr {absolute4, ".csb"}

pat dch					leaving loi 2

pat dup $1==4
with src4				yields %1 %1

pat dup $1==8
with src4 src4				yields %2 %1 %2 %1
with exact DLOCAL			yields %1 %1
with exact absolute8			yields %1 %1

pat dup $1>8
with STACK
    gen move {const4, $1}, r0
	jsr {absolute4, ".dup"}

pat dus $1==4
with src4 STACK
    gen move %1, r0
	jsr {absolute4, ".dup"}

pat exg $1==4
with src4 src4				yields %1 %2

pat exg $1==8
with src4 src4 src4 src4		yields %2 %1 %4 %3

pat exg
with STACK
    gen move {const4, $1}, r0
	jsr {absolute4, ".exg"}

pat fil
gen move {addr_external, $1}, {absolute4, "hol0"+4}

pat gto
with STACK
    gen move {addr_external, $1}, r0
	br {label, ".gto"}

pat lim					yields {absolute2, ".ignmask"}

pat lin
gen move {const4, $1}, {absolute4, "hol0"}

pat lni
gen addd {const4, 1}, {absolute4, "hol0"}

pat lor $1==0				yields fp

pat lor $1==1
with STACK				yields sp

pat lor $1==2				yields {absolute4, ".reghp"}

pat lpb					leaving adp 8

pat mon
with STACK
gen jsr {absolute4, ".mon"}

pat nop
with STACK
    gen move {absolute4, "hol0"}, {TOS}
	jsr {absolute4, ".print"}
	jsr {absolute4, ".prnl"}

pat rck $1==4
with STACK
    gen jsr {absolute4, ".rck"}

pat rtt					leaving ret 0

pat sig
with src4
uses REG
    gen move {absolute4, ".trpreg"}, %a
	move %1, {absolute4, ".trpreg"}		yields %a

pat sim
with src24
    gen movw %1, {absolute2, ".ignmask"}

pat str $1==0
with src4
gen sprd %1, fp

pat str $1==1
with src4
gen sprd %1, sp

pat str $1==2
with src4
gen move %1, {absolute4, ".reghp"}

pat trp
with STACK
    gen jsr {absolute4, ".trp"}
