SHAPES
#	it is more or less true that the costs = number of memory refs.
#	the cost is 1 for memory items, 0 for regs and building consts
#	$l and $r are used to account for multiple memory accesses
#	basic shapes
F:	'FREE';			# Execute the subtree for side effects
N:	'NAME'	:1;		# Name of (typically static variable)
				# cost = 2 wds address
T:	'TEMP'	:1;		# Temporary location in memory
				# cost = 1 wd offset
A:	'AUTO'  :1;		# Automatic Variable
P:	'PARAM' :1;		# function parameter
CC:	'CC';			# Execute for Condition Codes only
R:	'REG' :0;			# Value goes in a register

#	constants
C:	:1;		
C0:	CONVAL 0 :0;
C1:	CONVAL 1 :0;
C2:	CONVAL 2 :0;
C3:	CONVAL 3 :0;
C4:	CONVAL 4 :0;
C5:	CONVAL 5 :0;
C6:	CONVAL 6 :0;
C7:	CONVAL 7 :0;
C8:	CONVAL 8 :0;
C16:	CONVAL 16 :0;
C32:	CONVAL 32 :0;
C64:	CONVAL 64 :0;
C128:	CONVAL 128 :0;
C256:	CONVAL 256 :0;

CPOW2B: C1, C2, C4, C8, C16, C32, C64, C128, C256;

C0to7:	POSRANGE 3 :0;		# should really be [1-8]; is [0-7]
Cc:	SGRANGE 7 :1;		# Constant character
Cuc:	POSRANGE 8 :1;		# Constant character
Cs:	SGRANGE 15 :1;		# Constant short
Cus:	POSRANGE 16 :1;		# Constant unsigned short

#	more complicated address modes

C1to8:  C1, C2, C3, C4, C5, C6, C7, C8;
EA: (R+Cs),  R, (R-Cs);		# Offset from register
  # Double indexing
EEA:	R[lul]+R[p], ('CONV' R[s])+R[p];
CEEA: EEA + Cc;
AWDnR: *EA,T,N,P,A;			# Addressable Word, not Register
AWD: R, AWDnR;				# Addressable Word
SEEA: *EEA, *CEEA;
CPI: *(R ++ C1);    # character postincrement, etc.
SPI: *(R ++ C2);
LPI: *(R ++ C4);
CAWDnC: *(R -= C1) ,  CPI, AWD, SEEA ;	# Addresssable word for byte op
SAWDnC: *(R -= C2) ,  SPI, AWD, SEEA ;	# Addressable Word for short op
LAWDnC: *(R -= C4) ,  LPI, AWD, SEEA ;	# Addressable Word for long op
LAWDnCR: *(R -= C4) ,  LPI, AWDnR, SEEA ;# Addressable Word for long op
CAWD: C, CAWDnC;
CAWDn2: C, *(R -= C1) , CPI, AWDnR;  # no double indexing, so clear is OK
SAWD : C, SAWDnC;
LAWD : C, LAWDnC;
LAWDnR: C, LAWDnCR;
SFLD: 'FLD' SAWD ;
UCHR: 'CONV' CAWD[cuc];
SHRT: Cs, 'CONV' SAWD[s];
USHRT: 'CONV' SAWD[sus];
RCR: 'CONV' R[cucsuslul], R[cucsuslul];
BSHFT: (C1 << RCR);
CR: R[cucsuslul], C[cucsuslul];
PCR: R, C;
PTRSUB: LAWD[p] - PCR[p];

# for function returns when functions return simple structures
UREG: & R ;
UHALF: UREG + C2;

OPCODES
DCOST  :1;

'COMOP' F,F {$N} "" ;
'COMOP' F,R {$A $> $R} "Y" ;
'COMOP' F,CC {$C} "" ;

'GENLAB' F  {$N} "\L%L:\n" ;
'GENLAB' R  {$L} "\L%L:\n" ;
'GENLAB' CC  {$C} "\L%L:\n" ;

'GENUBR' F  {$N} "ZI" ;
'GENUBR' C0  {$N} "ZI" ;
'GENUBR' R  {$N} "ZI" ;
'GENBR' CC  {$N} "ZI" ;

'CM' F,F {$N} "";

'CALL' C,F {$A $1} "	jsr	CL\nZc" ;
'CALL' R,F {$A $< $1} "	jsr	(CL)\nZc" ;

'UCALL' C {$A $1} "	jsr	CL\n" ;
'UCALL' R {$A $< $1} "	jsr	(CL)\n" ;

	# MOVQ is 0 to offset Cc cost
= R[cucsuslul], Cc {$L} "	mov.l	AR,AL\n" :0;
= R[cucsuslul], Cc {$R} "	mov.l	AR,AL\n" :0;

= CAWD[cuc], C0 {$R} "	clr.b	AL\n" ;
= CAWD[cuc], R {$R} "RL!R	mov.b	AR,AL\n" ;
= CAWD[cuc], R {$C} "	mov.b	AR,AL\n" ;
= CAWD[cuc], CAWD[cuc] {$R} "RL!R	mov.b	AR,AL\n" ;
= CAWD[cuc], CAWD[cuc] {$C} "	mov.b	AR,AL\n" ;

= SAWD[sus], C0 {$R} "	clr.w	AL\n" ;
= SAWD[sus], R 	{$R} "RL!R	mov.w	AR,AL\n" ;
= SAWD[sus], R 	{$C} "	mov.w	AR,AL\n" ;
= SAWD[sus], SAWD[sus] 	{$R} "RL!R	mov.w	AR,AL\n" ;
= SAWD[sus], SAWD[sus] 	{$C} "	mov.w	AR,AL\n" ;

= LAWD[lul], C0 {$R $l } "	clr.l	AL\n" ;
= LAWD[lul], LAWD[lul] {$R $l $r} "RL!R	mov.l	AR,AL\n" ;
= LAWD[lul], LAWD[lul] {$C $l $r} "	mov.l	AR,AL\n" ;

	# note that moves to address registers don't set condition code
	# this is the reason for LAWDnR
= R[p], C0 "	sub.l	AL,AL\n" ;
= R[p], (&A)[p] "	lea.l	A(RL),AL\n" ;
= R[p], (&P)[p] "	lea.l	A(RL),AL\n" ;
= LAWD[p], R[plul] {$R $l} "RR!L\tmov.l	AR,AL\n";  # remember the register
= LAWD[p], LAWD[plul] {$l $r} "RL!R	mov.l	AR,AL\n";
= LAWDnR[p], LAWD[plul] {$R $C $l $r} "	mov.l	AR,AL\n";
= R[p], EA[p] {$r} "	lea.l	UR,AL\n" ;
= R[p], EEA[p] {$r} "	lea.l	UR,AL\n" ;
= R[p], CEEA[p] {$r} "	lea.l	UR,AL\n" ;

= SFLD[cuc], CAWD[cuc] {1 $R} "\tmov.b\tAR,A1\nH?L\tlsl.w\t&HL,A1\n\tand.w\t&ML,A1\n\tand.w\t&M~L,A-(LL)\n\tor.w\tA1,A(LL)\n" :5;

= SFLD[sus], SAWD[sus] {1 $R} "\tmov.w\tAR,A1\nH?L\tlsl.w\t&HL,A1\n\tand.w\t&ML,A1\n\tand.w\t&M~L,A-(LL)\n\tor.w\tA1,A(LL)\n" :5;

= SFLD[lul], LAWD[] {1 $R} "\tmov.l\tAR,A1\nH?L\tlsl.l\t&HL,A1\n\tand.l\t&ML,A1\n\tand.l\t&M~L,A-(LL)\n\tor.l\tA1,A(LL)\n" :5;

#  put the tests before the copies so the fast mode will work
CAWDnC[cuc] {$C} "	tst.b	AR\n" ;
SAWDnC[sus] {$C} "	tst.w	AR\n" ;
	# the 1 $< should ensure that %d0 is used here
R[p] {$C 1 $<} "	mov.l	AR,%d0\n" ;  # faster than compare...
LAWDnC[lulp] {$C $r} "	tst.l	AR\n" ;

Cc[lulsuscuc] {$1} "	mov.l	AR,A1\n" :0;  # MOVQ (cost 0 to offset Cc cost)
C0[p] {$1} "	sub.l	A1,A1\n" :1;

# these are quite high costs; really, sty should make the cost
# correspond to the address mode cost, but it doesn't (yet!)

CAWD[cuc] {$1 $>} "RR!1	mov.b	AR,A1\n" :1;
SAWD[sus] {$> $1} "RR!1	mov.w	AR,A1\n";
LAWD[plul] {$> $1 $r} "RR!1	mov.l	AR,A1\n";

#  for some reason (bug in sty?) this didn't work
# EA[p] {$1 $>} "	lea.l	U.,A1\n" ;

+ R[lul], R[p] {$1 $< $>} "	lea.l	U.,A1\n" ;
+ ('CONV' R[s]), R[p] {$1 $< $>} "	lea.l	U.,A1\n" ;
+ EEA, Cc {$1 $<} "	lea.l	U.,A1\n" :2;
+ R[p], Cs {$1 $<} "	lea.l	U.,A1\n" :2;
- R[p], Cs {$1 $<} "	lea.l	U.,A1\n" :2;

'UAND' A {$1 $>} "	lea.l	AL,A1\n" :2;
'UAND' P {$1 $>} "	lea.l	AL,A1\n" :2;
'UAND' T {$1 $>} "	lea.l	AL,A1\n" :2;

'FLD'[suscuc] SAWD[]  {$< $1 $C}
	"RL!1\tmov.w\tAL,A1\nH?.\tlsr.w\t&H.,A1\n\tand.w\t&N.,A1\n" :7;
'FLD'[lul] SAWD[]  {$< $1 $C}
	"RL!1\tmov.l\tAL,A1\nH?.\tlsr.l\t&H.,A1\n\tand.l\t&N.,A1\n" :7;

'ARG' (&A) {$N $l} "	pea.l	A(LL)Z0\n" ;
'ARG' (&P) {$N $l} "	pea.l	A(LL)Z0\n" ;
'ARG'[sus] SAWD[sus] {$N} "\tmov.w\tAL,Z1\n" ;
'ARG'[lul] SAWD[sus] {$N 1 $<}
	"\tmov.w\tAL,A1\n\tmov.l\tA1,Z2\n" ; # short structures
'ARG' LAWD[lulp]  {$N $l} "	mov.l	AL,Z2\n" ;
'ARG' EA[p] {$N} "	pea.l	ULZ0\n" :3;

'CMP' R[cuc], CAWDnC[cuc] {$C} "	cmp.b	AL,AR\n" ;
'CMP' R[sus], SAWDnC[sus] {$C} "	cmp.w	AL,AR\n" ;
'CMP' R[plul], LAWDnC[plul] {$C $r} "	cmp.l	AL,AR\n" ;
'CMP' CAWDnC[c], Cc {$C} "	cmp.b	AL,AR\n" ;
'CMP' CAWDnC[uc], Cuc {$C} "	cmp.b	AL,AR\n" ;
'CMP' CAWDnC[s], Cs {$C} "	cmp.w	AL,AR\n" ;
'CMP' CAWDnC[us], Cus {$C} "	cmp.w	AL,AR\n" ;
'CMP' LAWDnC[plul], C {$C $l $r} "	cmp.l	AL,AR\n" ;
'CMP' CPI, CPI {$C} "	cmp.b	AL,AR\n";
'CMP' SPI, SPI {$C} "	cmp.w	AL,AR\n";
'CMP' LPI, LPI {$C} "	cmp.l	AL,AR\n";

'UMINUS' R[lul]  {$1 $[} "RL!1	mov.l	AL,A1\n	neg.l	A1\n" ;
'UMINUS' R[sus]  {$1 $[} "RL!1	mov.w	AL,A1\n	neg.w	A1\n" ;
'UMINUS' R[cuc]  {$1 $[} "RL!1	mov.b	AL,A1\n	neg.b	A1\n" ;

~ R[lul]  {$1 $[} "RL!1	mov.l	AL,A1\n	not.l	A1\n" ;
~ R[sus]  {$1 $[} "RL!1	mov.w	AL,A1\n	not.w	A1\n" ;
~ R[cuc]  {$1 $[} "RL!1	mov.b	AL,A1\n	not.b	A1\n" ;

-- CAWD[cuc], C {$1 $l} "F\tmov.b\tA-L,A1\n\tsub.b\tAR,AL\n" :3;
++ CAWD[cuc], C {$1 $l} "F\tmov.b\tA-L,A1\n\tadd.b\tAR,AL\n" :2;
-- SAWD[sus], C {$1 $l} "F	mov.w	A-L,A1\n	sub.w	AR,AL\n" :2;
++ SAWD[sus], C {$1 $l} "F	mov.w	A-L,A1\n	add.w	AR,AL\n" :2;
-- LAWD[plul], C {$1 $l $l $l $r} "F\tmov.l\tA-L,A1\n\tsub.l\tAR,AL\n" :2;
++ LAWD[plul], C {$1 $l $l $l $r} "F\tmov.l\tA-L,A1\n\tadd.l\tAR,AL\n" :2;

& R[lulsuscuc], BSHFT {$C} "\tbtst\tA(RR),AL\n" :1;
& UCHR, BSHFT {$C} "\tbtst\tA(RR),AL\n" :2;
& R[lulsuscuc], CPOW2B {$C} "\tbtst\tZbAR,AL\n" :2;
& UCHR, CPOW2B {$C} "\tbtst\tZbAR,AL\n" :3;

&= CAWD[cuc], CR {$L $C} "	and.b	AR,AL\n" ;
&= R[cuc], CAWD[cuc] {$L $C} "	and.b	AR,AL\n" ;
&= SAWD[sus], CR {$L $C} "	and.w	AR,AL\n" ;
&= R[sus], SAWD[sus] {$L $C} "	and.w	AR,AL\n" ;
&= LAWD[lul], CR {$L $C $l $r} "	and.l	AR,AL\n" ;
&= R[lul], LAWD[lul] {$L $C $r} "	and.l	AR,AL\n" ;

|= CAWD[cuc], CR {$L $C} "	or.b	AR,AL\n" ;
|= R[cuc], CAWD[cuc] {$L $C} "	or.b	AR,AL\n" ;
|= SAWD[sus], CR {$L $C} "	or.w	AR,AL\n" ;
|= R[sus], SAWD[sus] {$L $C} "	or.w	AR,AL\n" ;
|= LAWD[lul], CR {$L $C $l $r} "	or.l	AR,AL\n" ;
|= R[lul], LAWD[lul] {$L $C $r} "	or.l	AR,AL\n" ;
|= R[lulsuscuc], CPOW2B {$L} "	bset	ZbAR,AL\n";
|= R[lulsuscuc], BSHFT {$L} "	bset	A(RR),AL\n";

	# ADDQ
+= CAWD[cuc], C1to8 {$L $C} "	add.b	AR,AL\n" ;
+= SAWD[sus], C1to8 {$L $C} "	add.w	AR,AL\n" ;
+= LAWD[lul], C1to8 {$L $C $l} "	add.l	AR,AL\n" ;
+= R[p], C1to8 {$L $C} "	add.l	AR,AL\n" ;
	# ordinary adds...
+= CAWD[cuc], CR {$L $C} "	add.b	AR,AL\n" ;
+= R[cuc], CAWD[cuc] {$L $C} "	add.b	AR,AL\n" ;
+= SAWD[sus], CR {$L $C} "	add.w	AR,AL\n" ;
+= R[sus], SAWD[sus] {$L $C} "	add.w	AR,AL\n" ;
+= LAWD[lul], CR {$L $C $l} "	add.l	AR,AL\n" ;
+= R[lul], LAWD[lul] {$L $C $r} "	add.l	AR,AL\n" ;
+= R[p], Cc  "	add.w	AR,AL\n" ;
+= R[p], ('CONV' R[s]) {$l} "	add.w	AR,AL\n" ;
+= LAWD[p], CR[lul] {$l} "	add.l	AR,AL\n" ;
+= R[p], LAWD[lul] {$r} "	add.l	AR,AL\n" ;
+= R[p], SHRT "	add.w	AR,AL\n" ;
+= LAWD[p], C[lulsus] {$l $r} "	add.l	AR,AL\n" ;

	# SUBQ
-= CAWD[cuc], C1to8 {$L $C} "	sub.b	AR,AL\n" ;
-= SAWD[sus], C1to8 {$L $C} "	sub.w	AR,AL\n" ;
-= LAWD[lul], C1to8 {$L $C $l} "	sub.l	AR,AL\n" ;
-= R[p], C1to8 {$L $C $l} "	sub.l	AR,AL\n" ;
-= CAWD[cuc], CR {$L $C} "	sub.b	AR,AL\n" ;
-= SAWD[sus], R[suslul] {$L $C} "	sub.w	AR,AL\n" ;
-= R[sus], SAWD[sus] {$L $C} "	sub.w	AR,AL\n" ;
-= SAWD[sus], C[suslul] {$L $C} "	sub.w	AR,AL\n" ;
-= LAWD[lul], R[lul] {$L $C $l} "	sub.l	AR,AL\n" ;
-= R[lul], LAWD[lul] {$L $C $r} "	sub.l	AR,AL\n" ;
-= LAWD[lul], C[lulsus] {$L $C $l $r} "	sub.l	AR,AL\n" ;
-= LAWD[p], R[lul]  {$l} "	sub.l	AR,AL\n" ;
-= R[p], LAWD[lul]  {$r} "	sub.l	AR,AL\n" ;
-= R[p], SHRT "	sub.w	AR,AL\n" ;
-= LAWD[p], C[lulsus] {$l} "	sub.l	AR,AL\n" ;

# pointer subtraction: note that A1 refers to a data register!
-  LAWD[p], LAWD[p] {$1 $< $l $r} "	mov.l	AL,A1\n	sub.l	AR,A1\n" :2;

^= CAWD[cuc], CR {$L $C } "	eor.b	AR,AL\n" ;
^= SAWD[sus], CR {$L $C } "	eor.w	AR,AL\n" ;
^= LAWD[lul], R[lul] {$L $C $l} "	eor.l	AR,AL\n" ;
^= LAWD[lul], C {$L $C $l $r} "	eor.l	AR,AL\n" ;

*= R[s], SAWD[s] {$1 $<} "	muls.w	AR,AL\n" ;
*= R[sus], SAWD[sus]  "	mulu.w	AR,AL\n" ;
*= SAWD[s], SAWD[s] {$1}
	"\tmov.w\tA-L,A1\n\tmuls.w\tAR,A1\n\tmov.w\tA1,AL\n" :3;
*= SAWD[sus], SAWD[sus] {$1}
	"\tmov.w\tA-L,A1\n\tmulu.w\tAR,A1\n\tmov.w\tA1,AL\n" :3;
* SHRT[l], Cs {$1 $[} "R(LL)!1	mov.w	A(LL),A1\n	muls.w	AR,A1\n";
* USHRT[ul], Cus {$1 $<} "R(LL)!1\tmov.w\tA(LL),A1\n	mulu.w	AR,A1\n";
* SHRT[l], SHRT[l] {$1 $<} "R(LL)!1\tmov.w\tA(LL),A1\n	muls.w	AR,A1\n";
/ PTRSUB, CPOW2B {$1}
	"R(LL)!1\tmov.l\tA(LL),A1\n\tsub.l\tA(LR),A1\n\tasr.l\tZbAR,A1\n" :2;
/= LAWD[ul], CPOW2B {$1}
		"RL!1\tmov.l\tAL,A1\n\tlsr.l\tZbAR,A1\nRL!1\tmov.l\tA1,AL\n";
/= SAWD[us], CPOW2B {$1}
		"RL!1\tmov.w\tAL,A1\n\tlsr.w\tZbAR,A1\nRL!1\tmov.w\tA1,AL\n";
/= CAWD[uc], CPOW2B {$1} 
		"RL!1\tmov.b\tAL,A1\n\tlsr.b\tZbAR,A1\nRL!1\tmov.b\tA1,AL\n";
/= R[s], SAWD[s] {$1 $[} "\text.l\tAL\n\tdivs.w\tAR,AL\n" :2;
/= R[sus], SAWD[sus] "	and.l	&0177777,AL\n	divu.w	AR,AL\n" :2;
/= SAWD[s], SAWD[s] {$1}
	"\tmov.w\tA-L,A1\n\text.l\tA1\n\tdivs.w\tAR,A1\n\tmov.w\tA1,AL\n" :4;
/= SAWD[sus], SAWD[sus] {$1}
     "\tmov.w\tA-L,A1\n\tand.l\t&0177777,A1\n\tdivu.w\tAR,A1\n\tmov.w\tA1,AL\n" 		:4;
/[suscuc] R[l], SHRT {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivs.w\tAR,A1\n" :3;
/[suscuc] R[lul], USHRT  {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivu.w\tAR,A1\n" :3;
/[suscuc] R[ul], Cus {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivu.w\tAR,A1\n" :3;
%= R[s], SAWD[s] "\text.l\tAL\n\tdivs.w\tAR,AL\n\tswap.w\tAL\n" :3;
%= R[sus], SAWD[sus] "\tand.l\t&0177777,AL\n\tdivu.w\tAR,AL\n\tswap.w\tAL\n"
	:4;

/ LAWD[l], LAWD[l] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tldiv%%\nZp" :10;
% LAWD[l], LAWD[l] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tlrem%%\nZp" :10;
* LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tlmul%%\nZp" :10;
/ LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tuldiv%%\nZp" :10;
% LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tulrem%%\nZp" :10;

# floating point ops
+ LAWD[df], LAWD[df] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tfladd%%\nZq" :3;
- LAWD[df], LAWD[df] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflsub%%\nZq" :3;
* LAWD[df], LAWD[df] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflmul%%\nZq" :3;
/ LAWD[df], LAWD[df] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tfldiv%%\nZq" :3;
= LAWD[df], LAWD[df] {$l $r} "\tmov.l\tAR,AL\n" ;
'CONV'[fd] LAWD[l] {2 $1 $< $l} "\tmov.l\tAL,Z2\n\tjsr\tltof%%\nZp" ;
'CONV'[fd] LAWD[ul] {2 $1 $< $l} "\tmov.l\tAL,Z2\n\tjsr\tultof%%\nZp" ;
# for the moment, to support both 16 and 32-bit machines, the
#	conversion ops for shorts are widened to longs
'CONV'[fd] LAWD[s] {2 $1 $<}
	"RL!1\tmov.w\tAL,A1\n\text.l\tA1\n\tmov.l\tAL,Z2\n\tjsr\tltof%%\nZp" ;
'CONV'[fd] LAWD[us] {2 $1 $<}
	"\tclr.w\tZ1\n\tmov.w\tAL,Z1\n\tjsr\tultof%%\nZp" ;
'CONV'[fd] LAWD[c] {2 $1 $<}
	"\tmov.b\tAL,%d0\n\text.w\t%d0\n\tmov.w\t%d0,Z2\n\tjsr\tltof%%\nZp" ;
'CONV'[fd] LAWD[uc] {2 $1 $<}
     "\tmov.b\tAL,%d0\n\tand.l\t&377,%d0\n\tmov.l\t%d0,Z2\n\tjsr\tultof%%\nZp";
'CONV'[cucsuslul] LAWD[fd] {2 $1 $< $l} "\tmov.l\tAL,Z2\n\tjsr\tftol%%\nZp" ;
'CONV'[fd] R[fd] {$1 $< $l} "RL!1\tmov.l\tAL,%d0\n" :0;
LAWD[df] {$1 $< $r} "\tmov.l\tAR,A1\n";
LAWD[df] {2 $C $> $r} "\tmov.l\tAR,Z2\n\tjsr\tfltst%%\nZp\ttst.w\t%d0\n" ;
'UMINUS' R[fd]  {$1 2 $<} "\tmov.l\tAL,Z2\n\tjsr\tflneg%%\nZp" ;
'CMP' LAWD[df], LAWD[df] {2 $C $< $> $l $r}
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflcmp%%\nZq\ttst.w\t%d0\n" :4;
'ARG' LAWD[fd]  {$N $l} "	mov.l	AL,Z2\n" ;

>>= SAWD[s], C1 {$C} "	asr.w	AR,AL\n" ;
>>= R[s], C1to8 {$C} "	asr.w	AR,AL\n" ;
>>= R[s], CR {$C} "	asr.w	AR,AL\n" ;
>>= R[l], C1to8 {$C} "	asr.l	AR,AL\n" ;
>>= R[l], CR {$C} "	asr.l	AR,AL\n" ;
>>= SAWD[us], C1 {$C} "	lsr.w	AR,AL\n" ;
>>= R[us], C1to8 {$C} "	lsr.w	AR,AL\n" ;
>>= R[sus], CR {$C} "	lsr.w	AR,AL\n" ;
>>= R[ul], C1to8 {$C} "	lsr.l	AR,AL\n" ;
>>= R[lul], CR {$C} "	lsr.l	AR,AL\n" ;

<<= R[sus], C1 {$C} "	add.w	AL,AL\n" ;
<<= SAWD[sus], C1 {$C} "	lsl.w	AR,AL\n" ;
<<= R[sus], C1to8 {$C} "	lsl.w	AR,AL\n" ;
<<= R[sus], CR {$C} "	lsl.w	AR,AL\n" ;
<<= R[lul], C1 {$C} "	add.l	AL,AL\n" ;
<<= R[lul], C1to8 {$C} "	lsl.l	AR,AL\n" ;
<<= R[lul], CR {$C} "	lsl.l	AR,AL\n" ;

'CONV'[cuc] R[lulsuscuc] "" :0;
'CONV'[sus] R[lulsus] "" :0;
'CONV'[cucsus] LAWD[lul] {$C $1 $< $l} "	mov.l	AL,A1\n" ;
'CONV'[cucsus] SAWD[sus] {$C $1 $<} "	mov.w	AL,A1\n" ;
'CONV'[cucsuslul] LAWD[p] {$C $< $1 $l} "	mov.l	AL,A1\n" ;

'CONV'[sus] CAWD[c] {$C $1 $[} "RL!1\tmov.b\tAL,A1\n\text.w\tA1\n" :2;
'CONV'[sus] R[uc] {$C $< $1} "RL!1	mov.w	AL,A1\n	and.w	&0377,A1\n" :3;
'CONV'[sus] CAWDn2[uc] {$1 $<} "Y	clr.w	A1\n	mov.b	AL,A1\n" :2;
'CONV'[sus] SEEA[uc] {$C $[ $1} "	mov.b	AL,A1\n	and.w	&0377,A1\n" :3;
'CONV'[sus] SEEA[uc] {$1} "	clr.w	A1\n	mov.b	AL,A1\n" :2;

'CONV'[lul] CAWD[c] {$C $1 $[}
	"RL!1\tmov.b\tAL,A1\n\text.w\tA1\n\text.l\tA1\n" :3;
'CONV'[lul] R[uc] {$C $1} "RR!1	mov.w	AL,A1\n	and.l	&0377,A1\n" :3;
'CONV'[lul] CAWDn2[uc] {$1 $<} "Y	clr.l	A1\n	mov.b	AL,A1\n" :2;
'CONV'[lul] SEEA[uc] {$C $[ $1} "	mov.b	AL,A1\n	and.l	&0377,A1\n" :3;
'CONV'[lul] SEEA[uc] {$1} "	clr.l	A1\n	mov.b	AL,A1\n" :2;
'CONV'[lul] SAWD[s] {$C $1 $[} "RL!1	mov.w	AL,A1\n	ext.l	A1\n" :2;
'CONV'[lul] SAWD[us] {$1} "	clr.l	A1\n	mov.w	AL,A1\n" :2;
'CONV'[lul] SAWD[us] {$1 $[} "RL!1\tmov.w\tAL,A1\n\tand.l\t&0177777,A1\n" :4;

'CONV'[p] SAWD[s] {$< $1} "	mov.w	AL,A1\n" ;
'CONV'[p] R[us] {$< $1} "\tand.l\t&0177777,AL\n\tmov.l\tAL,A1\n" :4;
'CONV'[p] LAWD[lul] {$< $1 $l} "	mov.l	AL,A1\n" ;

'STARG' R  {2 $< $N} "ZS" ;
'STASG' R,R {$R} "ZSFZz" ;
'STASG' LAWD,R {1 $< $R} "	mov.l	AL,A1\nZsFZz" :2;

# for f().x where f returns a simple structure
'STAR' [sus] UREG {$1 $[} "	swap.w	A1\n" ;
'STAR' [sus] UHALF {$1 $[} "" :0;

# 'INIT'[cuc] C {$N} "	byte	CL\n" ;
# 'INIT'[sus] C {$N} "	short	CL\n" ;
'INIT'[plul] C {$N} "	long	CL\n" ;
