#ident "@(#)stin	35.1     88/08/26     "
#ident "Copyright (c) 1984 AT&T, INC. and MOTOROLA, INC."
:ctl @
@dcl proc, eakey
@asg eakey=FALSE
@if @proc@ != M68000 & @proc@ != M68010
@asg eakey=TRUE
@end
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

#	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
FC:	'FCON'  :0;		# floating point constant
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;
SCL:    POSRANGE 2 :0;		# INDEX REGISTER SCALING FACTORS (0,1,2,3)

CPOW2:		USERCOST 1 :0;	# any power of 2
CPOW2SUM:	USERCOST 2 :0;	# the sum of 2 powers of 2 (e.g. 10 = 8 + 2)
CPOW2DIF:	USERCOST 3 :0;	# the diff. of powers of 2 (e.g. 14 = 16 - 2)

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
C7bit:	SGRANGE 6 :1;		# Short displacement which can be added to
C15BIT:	POSRANGE 15 :1;		# Constant positive word

# Immediate Constants

C1to8:  C1, C2, C3, C4, C5, C6, C7, C8;

# Modes not using a D register

EA: (R[p]+Cs),R[p],(R[p]-Cs);   # Offset from register
@if @eakey@ != TRUE
IND: *EA, A, P, N;		# INDirect modes



AWDnR: IND;                     # Addressable Word, not Register
@end
@if @eakey@ = TRUE
IND: *EA, A, P, N;		# INDirect modes
INDD: (IND+C);                  # INDirect with outer Displacement
DIND: *INDD, *IND;		# Double INDirect
AWDnR: IND,DIND;		# Addressable WorD, not Register
@end
AWD: R, T, AWDnR;		# Addressable WorD (temp in reg?)

# Index Register

IR: ('CONV' R[s]), R[lul];        # Index Register
@if @eakey@ != TRUE

IRD:  (IR+Cc);                  # Index Register with 8-bit Displacement
@end
@if @eakey@ = TRUE
SIR: (IR<<SCL); 		# Scaled Index Register
SIRD: IR, SIR, (SIR+C);		# Scaled Index Register w/optional Displacement
@end
# Modes using a D register (index register)

LVAL: &A, &P, R[p], &N;
@if @eakey@ != TRUE
LVALD: R[p]+Cs, C[p];
EEA: IR+R[p];
CEEA: EEA+Cc;
IEEA: *EEA;       # Indirect modes using  D-reg
@end
@if @eakey@ = TRUE
LVALD: R[p]+C, C[p];
EEA: IR+LVAL,SIR+LVAL,LVAL+R;	# index plus base
CEEA:EEA+C,IR+LVALD,SIR+LVALD;  # index plus base with displacement
IEEA: *CEEA, *SIRD, *EEA;       # Indirect modes using  D-reg

# Double Indirect

#   Preindirect indexing

DInD: *IEEA;			# Double Indirect modes, D-reg, no outer disp
DID: DInD, *(IEEA+C);		# Double Indirect with optional outer disp

#   Postindirect indexing

II: IR+IND, SIR+IND;          # Indirect Index
PID: IR+INDD, SIR+INDD;       # Post Indirect with Displacement
PII: *PID,*II,*INDD,*IND;     # Post Indirect Index

SEEA: IEEA, PII, DID;		# Effective address modes using  D-reg
@end
@if @eakey@ != TRUE
SEEA: *EEA, *CEEA;
@end
CPI: *(R ++ C1);    		# character postincrement, etc.
SPI: *(R ++ C2);
LPI: *(R ++ C4);
DPI: *(R ++ C8);
CAWDnC: *(R -= C1) ,  CPI, SEEA, AWD;	# Addresssable word for byte op
SAWDnC: *(R -= C2) ,  SPI, SEEA, AWD;	# Addressable Word for short op
LAWDnC: *(R -= C4) ,  LPI, SEEA, AWD;	# Addressable Word for long op
DAWDnC: AWD;			        # No Double indexing.   No -=8, +=8
DAWDnC881: *(R -= C8) ,  DPI,SEEA, AWD;	# Full 881, Addressable Double word 
LAWDnCR: *(R -= C4) ,  LPI, SEEA, AWDnR;# 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;
DAWD : FC, DAWDnC[d];			#Addressable Double. No double indexing
DAWD881 : FC, DAWDnC881[d];             #Addressable Double. Full 881
LAWDnR: C, LAWDnCR;
CAWDNP: C, SEEA, AWD;			#no predecrement or postincrement
SAWDNP: C, SEEA, AWD;			#no predecrement or postincrement
LAWDNP: C, SEEA, AWD;			#no predecrement or postincrement
CVSLAWD: 'CONV' LAWD[cls];
FLTDBL:    DAWD,    LAWDnC[f];	#'CONV' LAWDnC[df];
FLTDBL881: DAWD881, LAWDnC[f]; #'CONV' LAWDnC[df];
SCFLD: 'FLD' CAWDNP ;
SSFLD: 'FLD' SAWDNP ;
SLFLD: 'FLD' LAWDNP ;
UCHR: 'CONV' CAWD[cuc];
SHRT: Cs, 'CONV' SAWD[s];
USHRT: 'CONV' SAWD[sus];
RCR: 'CONV' R[cucsuslul], R[cucsuslul];
CRCR: C, RCR;
BSHFT: (C1 << RCR);
CR: R[cucsuslul], C[cucsuslul];
PCR: R, C;
PTRSUB: LAWD[p] - PCR[p];
EXTEND: AWDnR, *EEA , *(EEA + C7bit);	# Address allowing subsequent byte

					#  access (non register)

# for function returns when functions return simple structures
UREG: & R ;
UHALF: UREG + C2;
FARG: 'ARG' FLTDBL;	# fortran intrinsic function argument
###############################################################
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  {$L} "ZI" ;

'GOTO' (*N) {$N $A}	"\tmov.l\tA(LL),%a0\n\tjmp\t\(%a0\)\n";
'FCALL' N, FARG {$U4 $1}	"\tZCL.ZT(RL)\tA(RL),A1\n" ;

'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;
@if @eakey@ != TRUE
= SLFLD[c], C0 {1 $R} "\tmov.b\t&M-L,A1\n\and.b\tA1,AL\n";
= SLFLD[s], C0 {1 $R} "\tmov.w\t&M-L,A1\n\and.w\tA1,AL\n";
= SLFLD[l], C0 {1 $R} "\tmov.l\t&M-L,A1\n\and.l\tA1,AL\n";

= CAWD[uc], SCFLD[cuc]  {1 $1 $C}
	"RR!1\tmov.b\tAR,A1\nH?R\tlsr.b\t&HR,A1\n\tand.b\t&NR,A1\n\tmov.b\tA1,AL\n" :9;

= SAWD[us], SSFLD[sus]  {1 $1 $C}
	"RR!1\tmov.w\tAR,A1\nH?R\tlsr.w\t&HR,A1\n\tand.w\t&NR,A1\n\tmov.w\tA1,AL\n" :9;

= LAWD[ul], SLFLD[lul]  {1 $1 $C}
	"RR!1\tmov.l\tAR,A1\nH?R\tlsr.l\t&HR,A1\n\tand.l\t&NR,A1\n\tmov.l\tA1,AL\n" :9;

= CAWD[c], SCFLD[cuc]  {1 $1 $C}
	"RR!1\tmov.b\tAR,A1\nH?R\tlsl.b\t&8-SR-HR,A1\n\tasr.b\t&8-SR,A1\n\tmov.b\tA1,AL\n" :7;

= SAWD[s], SSFLD[sus]  {1 $1 $C}
	"RR!1\tmov.w\tAR,A1\nH?R\tlsl.w\t&16-SR-HR,A1\n\tasr.w\t&16-SR,A1\n\tmov.w\tA1,AL\n" :9;

= LAWD[l], SLFLD[lul]  {1 $1 $C}
	"RR!1\tmov.l\tAR,A1\nH?R\tlsl.l\t&32-SR-HR,A1\n\tasr.l\t&32-SR,A1\n\tmov.l\tA1,AL\n" :9;
#
#	Convert sign on field extractions.
#
'CONV'[cuc] SLFLD[c]  {1 $1 $C $<}
	"RR!1\tmov.b\tAR,A1\nH?L\tlsl.b\t&8-S-HR,A1\n\tasr.b\t&8-SR,A1\n" :7;

'CONV'[sus] SLFLD[s]  {1 $1 $C $<}
	"RR!1\tmov.w\tAR,A1\nH?L\tlsl.w\t&16-S-HR,A1\n\tasr.w\t&16-SR,A1\n" :7;

'CONV'[lul]  SLFLD[l]  {1 $1 $C $<}
	"RR!1\tmov.l\tAR,A1\nH?L\tlsl.l\t&32-S-HR,A1\n\tasr.l\t&32-SR,A1\n" :7;

'CONV'[cucsuslul] SLFLD[uc]  {1 $1 $C $<}
	"RR!1\tmov.b\tAL,A1\nH?L\tlsr.l\t&HL,A1\n\tand.l\t&NL,A1\n" :7;

'CONV'[cucsuslul] SLFLD[us]  {1 $1 $C $<}
	"RR!1\tmov.w\tAL,A1\nH?L\tlsr.l\t&HL,A1\n\tand.l\t&NL,A1\n" :7;

'CONV'[cucsuslul] SLFLD[ul]  {1 $1 $C $<}
	"RR!1\tmov.l\tAL,A1\nH?L\tlsr.l\t&HL,A1\n\tand.l\t&NL,A1\n" :7;
@end
@if @eakey@ = TRUE
= SLFLD[], C0 {$R} "\tbfclr\tAL{&ZhL:&SL}\n";

= CAWD[uc], SCFLD[]  {1 $1 $C} 
	"\tbfextu\tAR{&ZhR:&SR},A1\n\tmov.b\tA1,AL\n";

= SAWD[us], SSFLD[]  {1 $1 $C} 
	"\tbfextu\tAR{&ZhR:&SR},A1\n\tmov.w\tA1,AL\n";

= LAWD[ul], SLFLD[]  {1 $1 $C} 
	"\tbfextu\tAR{&ZhR:&SR},A1\n\tmov.l\tA1,AL\n";

= CAWD[c], SCFLD[]  {1 $1 $C} 
	"\tbfexts\tAR{&ZhR:&SR},A1\n\tmov.b\tA1,AL\n";

= SAWD[s], SSFLD[]  {1 $1 $C} 
	"\tbfexts\tAR{&ZhR:&SR},A1\n\tmov.w\tA1,AL\n";

= LAWD[l], SLFLD[]  {1 $1 $C} 
	"\tbfexts\tAR{&ZhR:&SR},A1\n\tmov.l\tA1,AL\n";
#
#	Convert sign on field extractions.
#
'CONV'[cuc] SLFLD[c]  {1 $1 $C $<}
	"\tbfexts\tAL{&ZhL:&SL},A1\n";

'CONV'[sus] SLFLD[s]  {1 $1 $C $<}
	"\tbfexts\tAL{&ZhL:&SL},A1\n";

'CONV'[lul]  SLFLD[l]  {1 $1 $C $<}
	"\tbfexts\tAL{&ZhL:&SL},A1\n";

'CONV'[cucsuslul] SLFLD[uc]  {1 $1 $C $<}
	"\tbfextu\tAL{&ZhL:&SL},A1\n";

'CONV'[cucsuslul] SLFLD[us]  {1 $1 $C $<}
	"\tbfextu\tAL{&ZhL:&SL},A1\n";

'CONV'[cucsuslul] SLFLD[ul]  {1 $1 $C $<}
	"\tbfextu\tAL{&ZhL:&SL},A1\n";
@end
= CAWD[cuc], C0 {$R} "	clr.b	AL\n" ;
= R[cuc], CAWD[cuc] {$L} "RL!R	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" ;
= R[sus], SAWD[sus] 	{$L} "RL!R	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    } "\tclr.l\tAL\n" ;
= R[lul], LAWD[lul] {$L   } "RL!R\tmov.l\tAR,AL\n" ;
= LAWD[lul], LAWD[lul] {$R      } "RL!R\tmov.l\tAR,AL\n" ;
= LAWD[lul], LAWD[lul] {$C      } "\tmov.l\tAR,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   } "RR!L\tmov.l\tAR,AL\n";  # remember the register
= LAWDnR[p], C0 {$L $C} "\tclr.l\tAL\n";
= LAWD[p], LAWD[plul] {     } "RL!R\tmov.l\tAR,AL\n";
= LAWDnR[p], LAWD[plul] {$R $C      } "\tmov.l\tAR,AL\n";
#= R[p], EA[p] {  } "    lea.l   UR,AL\n" ;
#= R[p], EEA[p] {  } "   lea.l   UR,AL\n" ;
#= R[p], CEEA[p] {  } "  lea.l   UR,AL\n" ;
@if @eakey@ = TRUE
= SCFLD[], LAWDNP[cuc] {1 $L}  "RR!1\tmov.b\tAR,A1\n\tbfins\tA1,AL{&ZhL:&SL}\n";

= SSFLD[], LAWDNP[sus] {1 $L}  "RR!1\tmov.w\tAR,A1\n\tbfins\tA1,AL{&ZhL:&SL}\n";

= SLFLD[], LAWDNP[lul] {1 $L}  "RR!1\tmov.l\tAR,A1\n\tbfins\tA1,AL{&ZhL:&SL}\n";
@end
@if @eakey@ != TRUE
= SCFLD[cuc], CAWD[cuc] {1 $L} "\tmov.b\tAR,A1\nH?L\tlsl.b\t&HL,A1\n\tand.b\t&ML,A1\n\tand.b\t&M~L,A-(LL)\n\tor.b\tA1,A(LL)\n" :9;

= SSFLD[sus], SAWD[sus] {2 $L} "\tmov.w\tAR,A1\nH?L\tmov.l\t&HL,A2\n\tlsl.w\tA2,A1\n\tand.w\t&ML,A1\n\tand.w\t&M~L,A-(LL)\n\tor.w\tA1,A(LL)\n" :12;

= SLFLD[lul], LAWD[] {1 $L} "\tmov.l\tAR,A1\nH?L\tmov.l\t&HL,A2\n\tlsl.l\tA2,A1\n\tand.l\t&ML,A1\n\tand.l\t&M~L,A-(LL)\n\tor.l\tA1,A(LL)\n" :12;
@end
#  put the tests before the copies so the fast mode will work
@if @eakey@ = TRUE
SLFLD[] {$C} "\tbftst\tAR{&ZhR:&SR}\n";
@end
CAWDnC[cuc] {$C} "	tst.b	AR\n" ;
SAWDnC[sus] {$C} "	tst.w	AR\n" ;
'CONV'[lul] CAWDnC[cuc] {$C} "	tst.b	AR\n" ;
'CONV'[lul] SAWDnC[sus] {$C} "	tst.w	AR\n" ;
'CONV'[lul] LAWDnC[lul] {$C} "  tst.l   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   } "  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!)
@if @eakey@ = TRUE
PII[cuc] { $1 $> } "RR!1	mov.b	AR,A1\n":2;
PII[sus] { $1 $> } "RR!1	mov.w	AR,A1\n":2;
PII[plul] { $1 $> } "RR!1	mov.l	AR,A1\n":2;
DID[cuc] { $1 $> } "RR!1	mov.b	AR,A1\n":2;
DID[sus] { $1 $> } "RR!1	mov.w	AR,A1\n":2;
DID[plul] { $1 $> } "RR!1	mov.l	AR,A1\n":2;
DIND[cuc] { $1 $> } "RR!1	mov.b	AR,A1\n":2;
DIND[sus] { $1 $> } "RR!1	mov.w	AR,A1\n":2;
DIND[plul] { $1 $> } "RR!1	mov.l	AR,A1\n":2;
@end
IEEA[cuc] { $1 $> } "RR!1	mov.b	AR,A1\n":2;
IEEA[sus] { $1 $> } "RR!1	mov.w	AR,A1\n":2;
IEEA[plul] { $1 $> } "RR!1	mov.l	AR,A1\n":2;
CAWD[cuc] {$1 $>} "RR!1	mov.b	AR,A1\n" :2;
SAWD[sus] {$> $1} "RR!1	mov.w	AR,A1\n":2;
LAWD[plul] {$> $1   } "RR!1     mov.l   AR,A1\n":2;



+[p] EEA, Cc {$1 $<} "   lea.l   U.,A1\n" :1;    # plus 1 for constant
+[p] R[p], Cs {$1 $<} "  lea.l   U.,A1\n" :1;    # plus 1 for constant
-[p] R[p], Cs {$1 $<} "  lea.l   U.,A1\n" :1;    # plus 1 for constant
@if @eakey@ = TRUE
+[p] EEA, C[slul]  {$1 $<} "   lea.l   U.,A1\n" :2;    # plus 2 for constant
+[p] R[p], C[slul]  {$1 $<} "  lea.l   U.,A1\n" :2;    # plus 2 for constant
-[p] R[p], C[slul]  {$1 $<} "  lea.l   U.,A1\n" :2;    # plus 2 for constant
@end
+[p] R[lul], R[p] {$1 $< $>} "\tlea.l   U.,A1\n" :2;
+[p] ('CONV' R[s]), R[p] {$1 $< $>} "\tlea.l   U.,A1\n" :2;
@if @eakey@ = TRUE
+[p] IND, C {$1 $<}"   lea.l   U.,A1\n":1;
+[p] SIR, C { $1 $<} "	lea.l	U.,A1\n":1;
+[p] SIR, R    {$1 $< $>}" lea.l   U.,A1\n":2;
+[p] IR, LVAL {$1 $< $>}"       lea.l   U.,A1\n":2;
+[p] SIR, LVAL {$1 $< $>}"	lea.l	U.,A1\n":2;
+[p] IEEA, C {$1 $<}"	lea.l	U.,A1\n":1;
+[p] IR, IND {$1 $< $>}"       lea.l   U.,A1\n":2;
+[p] SIR, IND {$1 $< $>}"      lea.l   U.,A1\n":2;
+[p] IR, INDD {$1 $< $>}"      lea.l   U.,A1\n":2;
+[p] SIR, INDD {$1 $< $>}"     lea.l   U.,A1\n":2;
@end

'UAND' A {$1 $>} "	lea.l	AL,A1\n" :1;
'UAND' P {$1 $>} "	lea.l	AL,A1\n" :1;
'UAND' T {$1} "ZtALA1" :5; # must store to mem if register temp
@if @eakey@ != TRUE
SLFLD[uc]  {$< $1 $C}
	"RL!1\tmov.b\tAL,A1\nH?.\tlsr.b\t&H.,A1\n\tand.b\t&N.,A1\n" :7;
SLFLD[us]  {$< $1 $C}
	"RL!1\tmov.w\tAL,A1\nH?.\tlsr.w\t&H.,A1\n\tand.w\t&N.,A1\n" :7;
SLFLD[ul]  {$< $1 $C}
	"RL!1\tmov.l\tAL,A1\nH?.\tlsr.l\t&H.,A1\n\tand.l\t&N.,A1\n" :7;
SLFLD[c]   {$< $1 $C}
	"RL!1\tmov.b\tAL,A1\nH?.\tlsl.l\t&32-S.-H.,A1\n\tasr.l\t&32-S.,A1\n" :7;
SLFLD[s]   {$< $1 $C}
	"RL!1\tmov.w\tAL,A1\nH?.\tlsl.l\t&32-S.-H.,A1\n\tasr.l\t&32-S.,A1\n" :7;
SLFLD[l]   {$< $1 $C}
	"RL!1\tmov.l\tAL,A1\nH?.\tlsl.l\t&32-S.-H.,A1\n\tasr.l\t&32-S.,A1\n" :7;
@end
@if @eakey@ = TRUE
SLFLD[ulucus] { $< $1 $C } "\tbfextu\tAL{&Zh.:&S.},A1\n":7;
SLFLD[lcs] { $< $1 $C } "\tbfexts\tAL{&Zh.:&S.},A1\n":7;
@end

'ARG' (&A) {$N   } "    pea.l   A(LL)Z0\n" ;
'ARG' (&P) {$N   } "    pea.l   A(LL)Z0\n" ;
'ARG'[lul] Cc {1 $N} "	mov.l	AL,A1\n	mov.l	A1,Z2\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   } "     mov.l   AL,Z2\n" ;
'ARG' EA[p] {$N} "	pea.l	ULZ0\n";
'ARG' LVALD[p] {$N} "	pea.l	ULZ0\n";
'ARG' EEA[p] {$N} "	pea.l	ULZ0\n";
'ARG' CEEA[p] {$N} "	pea.l	ULZ0\n";
@if @eakey@ = TRUE
'ARG' INDD[p] {$N} "    pea.l   ULZ0\n";
'ARG' II[p] {$N} "	pea.l	ULZ0\n";
'ARG' PID[p] {$N} "	pea.l	ULZ0\n";
@end
'CMP' CAWDnC[c], Cc {$C} "	cmp.b	AL,AR\n" ;
'CMP' CAWDnC[uc], Cuc {$C} "	cmp.b	AL,AR\n" ;
'CMP' R[cuc], CAWDnC[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' R[sus], SAWDnC[sus] {$C} "	cmp.w	AL,AR\n" ;
'CMP' R[plul], LAWDnC[plul] {$C   } "   cmp.l   AL,AR\n" ;
'CMP' LAWDnC[plul], C {$C      } "      cmp.l   AL,AR\n" :2;  # add 1 for long immediate
'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" :2;
++ 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         } "F\tmov.l\tA-L,A1\n\tsub.l\tAR,AL\n" :2;
++ LAWD[plul], C {$1 $l         } "F\tmov.l\tA-L,A1\n\tadd.l\tAR,AL\n" :2;
@if @eakey@ != TRUE
& EXTEND[lul], CPOW2 {$C} "\tbtst\tZBARAL\n" : 1;
& ('CONV' EXTEND[sus]), CPOW2 {$C} "\tbtst\tZBARA(LL)\n" : 1;
& R[lulsuscuc], BSHFT {$C} "\tbtst\tA(RR),AL\n" :2;
& UCHR, BSHFT {$C} "\tbtst\tA(RR),AL\n" :2;
& R[lulsuscuc], CPOW2 {$C} "\tbtst\tZbAR,AL\n" :3;
& UCHR, CPOW2B {$C} "\tbtst\tZbAR,AL\n" :3;
@end
& R[lul], Cc {1 $C} "\tmov.l\tAR,A1\n\tand.l\tAL,A1\n" :2;	#  cost = 3
& R[lulsus], C15BIT {1 $< $C} "RL!1\tmov.l\tAL,A1\n\tand.w\tAR,A1\n" :2;	#  cost = 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      } "        and.l   AR,AL\n" ;
&= R[lul], LAWD[lul] {$L $C   } "       and.l   AR,AL\n" ;

|= EXTEND[lulsuscuc], CPOW2 {$L} "\tbset\tZBARAL\n" : 1;
|= 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" ;
|= R[lulsus], Cus {$L} "\tor.w\tAR,AL\n" :2;
|= R[lulsuscuc], CPOW2 {$L} "	bset	ZbAR,AL\n" :3;
|= R[lulsuscuc], BSHFT {$L} "	bset	A(RR),AL\n" :2;
|= LAWD[lul], CR {$L $C      } "        or.l    AR,AL\n" ;
|= R[lul], LAWD[lul] {$L $C   } "       or.l    AR,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   } "        add.l   AR,AL\n" ;
+= R[p], C1to8 {$L} "	add.l	AR,AL\n" :2; # 4 cy longer than D reg, no cc
	# 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   } "   add.l   AR,AL\n" ;
+= R[lul], LAWD[lul] {$L $C   } "       add.l   AR,AL\n" ;
+= R[p], Cc  "	add.w	AR,AL\n" :2;	# 4 cycles longer than D register
+= R[p], ('CONV' R[s])      "   add.w   AR,AL\n" :2;
+= LAWD[p], CR[lul]         "   add.l   AR,AL\n" :2;
+= R[p], LAWD[lul]      "       add.l   AR,AL\n" :2;
+= R[p], SHRT "	add.w	AR,AL\n" :2;
+= LAWD[p], C[lulsus]         " add.l   AR,AL\n" :2;

	# 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   } "        sub.l   AR,AL\n" ;
-= R[p], C1to8 {$L   } "        sub.l   AR,AL\n" :2;    #no cc
-= 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   } "       sub.l   AR,AL\n" ;
-= R[lul], LAWD[lul] {$L $C   } "       sub.l   AR,AL\n" ;
-= LAWD[lul], C[lulsus] {$L $C      } " sub.l   AR,AL\n" ;
-= LAWD[p], R[lul]       "      sub.l   AR,AL\n" :2;
-= R[p], LAWD[lul]       "      sub.l   AR,AL\n" :2;
-= R[p], SHRT "	sub.w	AR,AL\n" :2;
-= LAWD[p], C[lulsus]         " sub.l   AR,AL\n" :2;

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

^= EXTEND[lulsuscuc], CPOW2 {$L} "\tbchg\tZBARAL\n" : 1;
^= CAWD[cuc], CR {$L $C } "	eor.b	AR,AL\n" ;
^= SAWD[sus], CR {$L $C } "	eor.w	AR,AL\n" ;
^= R[lulsus], Cus {$L} "\teor.w\tAR,AL\n" :2;
^= R[lulsuscuc], CPOW2 {$L} "	bchg	ZbAR,AL\n" :3;
^= R[lulsuscuc], BSHFT {$L} "	bchg	A(RR),AL\n" :2;
^= LAWD[lul], R[lul] {$L $C   } "       eor.l   AR,AL\n" ;
^= LAWD[lul], C {$L $C      } " eor.l   AR,AL\n" ;

*= R[lul], CPOW2SUM {1 $L $C}
	"ZfARlAL\tmov.l\tAL,A1\nZdARlAL\tadd.l\tA1,AL\n";
*= R[sus], CPOW2SUM {1 $L $C}
	"ZfARwAL\tmov.w\tAL,A1\nZdARwAL\tadd.w\tA1,AL\n";
*= R[cuc], CPOW2SUM {1 $L $C}
	"ZfARbAL\tmov.b\tAL,A1\nZdARbAL\tadd.b\tA1,AL\n";
*= R[lul], CPOW2DIF {1 $L $C}
	"ZfARlAL\tmov.l\tAL,A1\nZDARlAL\tsub.l\tA1,AL\n";
*= R[sus], CPOW2DIF {1 $L $C}
	"ZfARwAL\tmov.w\tAL,A1\nZDARwAL\tsub.w\tA1,AL\n";
*= R[cuc], CPOW2DIF {1 $L $C}
	"ZfARbAL\tmov.b\tAL,A1\nZDARbAL\tsub.b\tA1,AL\n";
*= LAWD[lul], CPOW2SUM {2 $1 $C}
	"\tmov.l\tA-L,A1\nZfARlA1\tmov.l\tA1,A2\nZdARlA1\tadd.l\tA2,A1\n\tmov.l\tA1,AL\n" :2;
*= SAWD[sus], CPOW2SUM {2 $1 $C}
	"\tmov.w\tA-L,A1\nZfARwA1\tmov.w\tA1,A2\nZdARwA1\tadd.w\tA2,A1\n\tmov.w\tA1,AL\n" :2;
*= CAWD[cuc], CPOW2SUM {2 $1 $C}
	"\tmov.b\tA-L,A1\nZfARbA1\tmov.b\tA1,A2\nZdARbA1\tadd.b\tA2,A1\n\tmov.b\tA1,AL\n" :2;
*= LAWD[lul], CPOW2DIF {2 $1 $C}
	"\tmov.l\tA-L,A1\nZfARlA1\tmov.l\tA1,A2\nZDARlA1\tsub.l\tA2,A1\n\tmov.l\tA1,AL\n" :2;
*= SAWD[sus], CPOW2DIF {2 $1 $C}
	"\tmov.w\tA-L,A1\nZfARwA1\tmov.w\tA1,A2\nZDARwA1\tsub.w\tA2,A1\n\tmov.w\tA1,AL\n" :2;
*= CAWD[cuc], CPOW2DIF {2 $1 $C}
	"\tmov.b\tA-L,A1\nZfARbA1\tmov.b\tA1,A2\nZDARbA1\tsub.b\tA2,A1\n\tmov.b\tA1,AL\n" :2;
*= R[s], SAWD[s] {$L   } "	muls.w	AR,AL\n" :10;
*= R[sus], SAWD[sus]  "	mulu.w	AR,AL\n" :10;
*= SAWD[s], SAWD[s] {$1}
	"\tmov.w\tA-L,A1\n\tmuls.w\tAR,A1\n\tmov.w\tA1,AL\n" :13;
*= SAWD[sus], SAWD[sus] {$1}
	"\tmov.w\tA-L,A1\n\tmulu.w\tAR,A1\n\tmov.w\tA1,AL\n" :13;
* SHRT[l], Cs {$1 $[} "R(LL)!1	mov.w	A(LL),A1\n	muls.w	AR,A1\n" :10;
* USHRT[ul], Cus {$1 $<} "R(LL)!1\tmov.w\tA(LL),A1\n	mulu.w	AR,A1\n" :10;
* SHRT[l], SHRT[l] {$1 $<} "R(LL)!1\tmov.w\tA(LL),A1\n	muls.w	AR,A1\n" :10;
* USHRT[lul], USHRT[lul] {$1 $<} "R(LL)!1\tmov.w\tA(LL),A1\n\tmulu.w\tAR,A1\n":10;
/ PTRSUB, CPOW2 {$1}
	"R(LL)!1\tmov.l\tA(LL),A1\n\tsub.l\tA(LR),A1\n\tasr.l\tZbAR,A1\n" :2;
/= LAWD[ul], CPOW2 {1 $L $C}
		"RL!1\tmov.l\tA-L,A1\n\tlsr.l\tZbAR,A1\nRL!1\tmov.l\tA1,AL\n";
/= SAWD[us], CPOW2 {1 $L $C}
		"RL!1\tmov.w\tA-L,A1\n\tlsr.w\tZbAR,A1\nRL!1\tmov.w\tA1,AL\n";
/= CAWD[uc], CPOW2 {1 $L $C} 
		"RL!1\tmov.b\tA-L,A1\n\tlsr.b\tZbAR,A1\nRL!1\tmov.b\tA1,AL\n";
/= R[l], CPOW2B {$L $C}
	"\ttst.l\tAL\n\tbpl\tZL1\n\tneg.l\tAL\n\tlsr.l\tZbAR,AL\n\tneg.l\tAL\n\tbra\tZL2\nZl1:\tlsr.l\tZbAR,AL\nZl2:\n";
/= R[s], CPOW2B {$L $C}
	"\ttst.w\tAL\n\tbpl\tZL1\n\tneg.w\tAL\n\tlsr.w\tZbAR,AL\n\tneg.w\tAL\n\tbra\tZL2\nZl1:\tlsr.w\tZbAR,AL\nZl2:\n";
/= R[c], CPOW2B {$L $C} 
	"\ttst.b\tAL\n\tbpl\tZL1\n\tneg.b\tAL\n\tlsr.b\tZbAR,AL\n\tneg.b\tAL\n\tbra\tZL2\nZl1:\tlsr.b\tZbAR,AL\nZl2:\n";
/= LAWD[l], CPOW2B {$1 $C}
	"\tmov.l\tA-L,A1\n\tbpl\tZL1\n\tneg.l\tA1\n\tlsr.l\tZbAR,A1\n\tneg.l\tA1\n\tbra\tZL2\nZl1:\tlsr.l\tZbAR,A1\nZl2:\tmov.l\tA1,AL\n" :2;
/= SAWD[s], CPOW2B {$1 $C}
	"\tmov.w\tA-L,A1\n\tbpl\tZL1\n\tneg.w\tA1\n\tlsr.w\tZbAR,A1\n\tneg.w\tA1\n\tbra\tZL2\nZl1:\tlsr.w\tZbAR,A1\nZl2:\tmov.w\tA1,AL\n" :2;
/= CAWD[c], CPOW2B {$1 $C}
	"\tmov.b\tA-L,A1\n\tbpl\tZL1\n\tneg.b\tA1\n\tlsr.b\tZbAR,A1\n\tneg.b\tA1\n\tbra\tZL2\nZl1:\tlsr.b\tZbAR,A1\nZl2:\tmov.b\tA1,AL\n" :2;
/= R[l], CPOW2 {1 $L $C}
	"\tmov.l\tZbAR,A1\n\ttst.l\tAL\n\tbpl\tZL1\n\tneg.l\tAL\n\tlsr.l\tA1,AL\n\tneg.l\tAL\n\tbra\tZL2\nZl1:\tlsr.l\tA1,AL\nZl2:\n";
/= R[s], CPOW2 {1 $L $C}
	"\tmov.l\tZbAR,A1\n\ttst.w\tAL\n\tbpl\tZL1\n\tneg.w\tAL\n\tlsr.w\tA1,AL\n\tneg.w\tAL\n\tbra\tZL2\nZl1:\tlsr.w\tA1,AL\nZl2:\n";
/= LAWD[l], CPOW2 {2 $1 $C}
	"\tmov.l\tZbAR,A2\n\tmov.l\tA-L,A1\n\tbpl\tZL1\n\tneg.l\tA1\n\tlsr.l\tA2,A1\n\tneg.l\tA1\n\tbra\tZL2\nZl1:\tlsr.l\tA2,A1\nZl2:\tmov.l\tA1,AL\n":2;
/= SAWD[s], CPOW2 {2 $1 $C}
	"\tmov.l\tZbAR,A2\n\tmov.w\tA-L,A1\n\tbpl\tZL1\n\tneg.w\tA1\n\tlsr.w\tA2,A1\n\tneg.w\tA1\n\tbra\tZL2\nZl1:\tlsr.w\tA2,A1\nZl2:\tmov.w\tA1,AL\n":2;
@if @eakey@ = TRUE
/= R[s], SAWD[s] {$L   } "\text.l\tAL\n\tdivs.l\tAR,AL\n" :22;
/= R[sus], SAWD[sus] "\tswap.w\tAL\n\tclr.w\tAL\n\tswap.w\tAL\n	divu.l	AR,AL\n" :23;
/= SAWD[s], SAWD[s] {$1}
	"\tmov.w\tA-L,A1\n\text.l\tA1\n\tdivs.l\tAR,A1\n\tmov.w\tA1,AL\n" :24;
/= SAWD[sus], SAWD[sus] {$1}
     "\tmov.l\t&0,A1\n\tmov.w\tA-L,A1\n\tdivu.l\tAR,A1\n\tmov.w\tA1,AL\n" 		:24;
@end
@if @eakey@ != TRUE
/= R[s], SAWD[s] {$L   } "\text.l\tAL\n\tdivs.w\tAR,AL\n" :22;
/= R[sus], SAWD[sus] "\tswap.w\tAL\n\tclr.w\tAL\n\tswap.w\tAL\n	divu.w	AR,AL\n" :23;
/= 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" :24;
/= SAWD[sus], SAWD[sus] {$1}
     "\tmov.l\t&0,A1\n\tmov.w\tA-L,A1\n\tdivu.w\tAR,A1\n\tmov.w\tA1,AL\n" 		:24;
/[suscuc] R[l], SHRT {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivs.w\tAR,A1\n" :20;
/[suscuc] R[lul], USHRT  {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivu.w\tAR,A1\n" :20;
/[suscuc] R[ul], Cus {$1 $[} "RL!1\tmov.l\tAL,A1\n\tdivu.w\tAR,A1\n" :20;
@end
% LAWD[l], CPOW2 {$1 $< $C}
	"RL=1\ttst.l\tA1\nRL!1\tmov.l\tAL,A1\n\tbpl\tZL1\n\tneg.l\tA1\n\tand.l\tAR-1,A1\n\tneg.l\tA1\n\tbra\tZL2\nZl1:\tand.l\tAR-1,A1\nZl2:\n";
% SAWD[s], CPOW2 {$1 $< $C}
	"RL=1\ttst.w\tA1\nRL!1\tmov.w\tAL,A1\n\tbpl\tZL1\n\tneg.w\tA1\n\tand.w\tAR-1,A1\n\tneg.w\tA1\n\tbra\tZL2\nZl1:\tand.w\tAR-1,A1\nZl2:\n";
% CAWD[c], CPOW2 {$1 $< $C}
	"RL=1\ttst.b\tA1\nRL!1\tmov.b\tAL,A1\n\tbpl\tZL1\n\tneg.b\tA1\n\tand.b\tAR-1,A1\n\tneg.b\tA1\n\tbra\tZL2\nZl1:\tand.b\tAR-1,A1\nZl2:\n";
%= LAWD[ul], CPOW2 {$L $C}
	"\tand.l\tAR-1,AL\n";
%= SAWD[us], CPOW2 {$L $C}
	"\tand.w\tAR-1,AL\n";
%= CAWD[uc], CPOW2B {$L $C}
	"\tand.b\tAR-1,AL\n";
@if @eakey@ != TRUE
%= R[s], SAWD[s] "\text.l\tAL\n\tdivs.w\tAR,AL\n\tswap.w\tAL\n" :23;
%= R[sus], SAWD[sus] "\tswap.w\tAL\n\tclr.w\tAL\n\tswap.w\tAL\n\tdivu.w\tAR,AL\n\tswap.w\tAL\n"
	:24;
/ LAWD[l], LAWD[l] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tldiv%%\nZp" :30;
% LAWD[l], LAWD[l] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tlrem%%\nZp" :30;
* LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tlmul%%\nZp" :20;
/ LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tuldiv%%\nZp" :30;
% LAWD[lul], LAWD[lul] {2 $1 $< $> $l $r}
	"\tmov.l\tAR,Z2\nRL!1\tmov.l\tAL,%d0\n\tjsr\tulrem%%\nZp" :30;
@end
@if @eakey@ = TRUE
/ LAWD[l], LAWD[l] {1 $1 $<}
	"RL!1\tmov.l\tAL,A1\n\tdivs.l\tAR,A1\n" :30;
% LAWD[l], LAWD[l] {2 $2 $<}
	"RL!1\tmov.l\tAL,A1\n\tmov.l\t&0,A2\n\ttdivs.l\tAR,A2:A1\n" :30;
*= R[l], LAWD[l] {$L}	"\tmuls.l\tAR,AL\n" :20;
*= R[lul], LAWD[lul] {$L}	"\tmulu.l\tAR,AL\n" :20;
* LAWD[l], LAWD[l] {1 $1 $<}
	"RL!1\tmov.l\tAL,A1\n\tmuls.l\tAR,A1\n" :20;
* LAWD[lul], LAWD[lul] {1 $1 $<}
	"RL!1\tmov.l\tAL,A1\n\tmulu.l\tAR,A1\n" :20;
/ LAWD[lul], LAWD[lul] {1 $1 $<}
	"RL!1\tmov.l\tAL,A1\n\tdivu.l\tAR,A1\n" :30;
% LAWD[lul], LAWD[lul] {2 $2 $<}
	"RL!1\tmov.l\tAL,A1\n\tmov.l\t&0,A2\n\ttdivu.l\tAR,A2:A1\n" :30;
@end
# The following  floating point patterns generate M68881  coprocessor
# instructions. They must occur before the non-M68881 paterns because
# many of the costs are the same as their non-M68881 counterparts.

= R[d], FC[d] {$U1 $L}       "\tfmov.d\tAR,AL\n";
= LAWDnR[d], FC[d] {$U1 $R}  "\tmov.l\tZwR,A-L\n\tmov.l\tZxR,ZnAL\n";
= LAWDnR[f], FC[f] {$U1 $R}  "\tmov.l\tAR,AL\n";
= FLTDBL881, R[df] {$U1 $R $C}  "\tfmov.ZTL\tAR,AL\n";
= FLTDBL881, ('CONV' R[fd]) {$U1 $L} "\tfmov.ZTL\tAR,AL\n";
= LAWDnC[lsc], FLTDBL881 {$U1 $A $L $>} 
		"\tfintrz.ZTR\tAR,%fp0\n\tfmov.ZTL\t%fp0,AL\n";
= LAWDnC[ul], FLTDBL881 {$U1 $A $L $>}
	"\tfintrz.ZTR\tAR,%fp0\n\tfbge\tZL1\n\tfmov.l\t%fp0,%d0\n\tbra\tZL2\nZl1:\tfsub.s\t&0x4f0000000,%fp0\n\tfmov.l\t%fp0,%d0\n\tadd.l\t&0x80000000,%d0\nZl2:\tmov.ZTL %d0,AL\n";
= LAWDnC[us], FLTDBL881 {$U1 $A $L $>}
	"\tfintrz.ZTR\tAR,%fp0\n\tfmov.l\t%fp0,%d0\n\tmov.w\t%d0,AL\n";
= LAWDnC[uc], FLTDBL881 {$U1 $A $L $>}
	"\tfintrz.ZTR\tAR,%fp0\n\tfmov.l\t%fp0,%d0\n\tmov.b\t%d0,AL\n";
= LAWDnC[lsc], ('CONV' R[fd]) {$U1 $L $A}
	"\tfintrz.x\tAR,%fp0\n\tfmov.ZTL\t%fp0,AL\n";
= LAWDnC[ul], ('CONV' R[fd])  {$U1 $A $L $>}
	"\tfintrz.ZTR\tAR,%fp0\n\tfbge\tZL1\n\tfmov.l\t%fp0,%d0\n\tbra\tZL2\nZl1:\tfsub.s\t&0x4f0000000,%fp0\n\tfmov.l\t%fp0,%d0\n\tadd.l\t&0x80000000,%d0\nZl2:\tmov.ZTL %d0,AL\n";
= LAWDnC[usuc], ('CONV' R[fd])  {$U1 $A $L $>}
	"\tfintrz.ZTR\tAR,%fp0\n\tfmov.l\t%fp0,%d0\n\tmov.ZTL\t%d0,AL\n";
= R[df], FLTDBL881 {$U1 $L}  "\tfmov.ZTR\tAR,AL\n";
= FLTDBL881, FLTDBL881 {1 $U1 $L $C} 
	"RR!1\tfmov.ZTR\tAR,A1\n\tfmov.ZTL\tA1,AL\n";

# the following two patterns handle register TEMPS

= T[fd], FLTDBL881 {1 $U1 $U2 $R $C}
	"RR!1\tfmov.ZTR\tAR,A1\n\tfmov.ZTR\tA1,AL\n";
= FLTDBL881, T {1 $U1 $U2 $R $C}
	"RR!1\tfmov.ZTR\tAR,A1\n\tfmov.ZTL\tA1,AL\n";

# M68881 double point and floating point ops

+= R[fd], FC   {$U1 $L $C}   "\tfadd.d\tAR,AL\n";
+= R[fd], FLTDBL881   {$U1 $L $C}   "\tfadd.ZTR\tAR,AL\n";
+ FLTDBL881, FLTDBL881 {$U1 $1 $<}
	"RL!1\tfmov.ZTL\tAL,A1\n\tfadd.ZTR\tAR,A1\n";
-= R[fd], FC  {$U1 $L $C}   "\tfsub.d\tAR,AL\n";
-[df] FLTDBL881, FLTDBL881 {$U1 $1 $C $<}
	"RL!1\tfmov.ZTL\tAL,A1\n\tfsub.ZTR\tAR,A1\n";
# Following seem to be covered by previous line.
#- FLTDBL881, FLTDBL881 {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfsub.ZTR\tAR,A1\n";
#- FLTDBL881, CVSLAWD {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfsub.ZTR\tAR,A1\n";
#- CVSLAWD, FLTDBL881 {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfsub.ZTR\tAR,A1\n";
*= R[fd], FC   {$U1 $L $C}   "\tfmul.d\tAR,AL\n";
*= R[fd], FLTDBL881   {$U1 $L $C}   "\tfmul.ZTR\tAR,AL\n";
* FLTDBL881, FLTDBL881 {$U1 $1 $C $<}
	"RL!1\tfmov.ZTL\tAL,A1\n\tfmul.ZTR\tAR,A1\n";
#* FLTDBL881, CVSLAWD {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfmul.ZTR\tAR,A1\n";
/= R[fd], FC   {$U1 $L $C}   "\tfdiv.d\tAR,AL\n";
/ FLTDBL881[fd], FLTDBL881 {$U1 $1 $C $<}
	"RL!1\tfmov.ZTL\tAL,A1\n\tfdiv.ZTR\tAR,A1\n";
#/ FLTDBL881, CVSLAWD {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfdiv.ZTR\tAR,A1\n";
#/ CVSLAWD, FLTDBL881 {$U1 $1 $C $<}
#	"RL!1\tfmov.ZTL\tAL,A1\n\tfdiv.ZTR\tAR,A1\n";
#

# M68881 Convert to/from double/float
#
'CONV'[df] LAWD[dflsc] {$U1 $A $1 $<}	"\tfmov.ZT.\tAL,A1\n" :0;
'CONV'[df] LAWD[ul] {$U1 $A $1 $<}
	"\tfmov.l\tAL,A1\n\tfbge\tZL1\n\tfadd.s\t&0x4f800000,A1\nZl1:\n";
'CONV'[df] SAWD[us] {$U1 $A $1 $<}
	"\tmov.w\tA-L,%d0\n\tand.l\t&0xffff,%d0\n\tfmov.l\t%d0,A1\n";
'CONV'[df] CAWD[uc] {$U1 $A $1 $<}
	"\tmov.b\tA-L,%d0\n\tand.l\t&0377,%d0\n\tfmov.l\t%d0,A1\n";

'CONV'[csl] LAWD[df] {$U1 $1 $< $A}
	"\tfintrz.ZT.\tAL,%fp0\n\tfmov.l\t%fp0,%d0\n";
'CONV'[csl] LAWD[df] {$U1 $1 $< $A $C}
	"\tfintrz.ZT.\tAL,%fp0\n\tfmov.l\t%fp0,%d0\n\ttst.l\t%d0\n";
'CONV'[ul] LAWDnC[df] {$U1 $1 $< $A}
	"	fintrz.ZT.	AL,%fp0\n	fbge	ZL1\n	fmov.l	%fp0,%d0\n	bra	ZL2\nZl1:	fsub.s	&0x4f0000000,%fp0\n	fmov.l	%fp0,%d0\n	add.l	&0x80000000,%d0\nZl2:\n";
'CONV'[ul] LAWDnC[df] {$U1 $1 $< $A $C}
	"	fintrz.ZT.	AL,%fp0\n	fbge	ZL1\n	fmov.l	%fp0,%d0\n	bra	ZL2\nZl1:	fsub.s	&0x4f0000000,%fp0\n	fmov.l	%fp0,%d0\n	add.l	&0x80000000,%d0\nZl2:\ttst.l\t%d0\n";
'CONV'[us] LAWDnC[df] {$U1 $1 $< $A}
	"\tfintrz.ZT.\tAL,%fp0\n\tfmov.l\t%fp0,%d0\n";
'CONV'[uc] LAWDnC[df] {$U1 $1 $< $A}
	"\tfintrz.ZT.\tAL,%fp0\n\tfmov.l\t%fp0,%d0\n";

#
# M68881 misc
#
'ARG' R[df] {$U1 $N} "\tfmov.d\tAL,ZF\n" ;		# 881 register arg
'UMINUS' T[df] {$U1 $U2 $L $C} "\tfneg.ZTL\tAL,AL\n" ;
'UMINUS' FLTDBL881  {$U1 $1 $< $C} "\tfneg.ZTL\tAL,A1\n" ;
'CMP' R[df], FC {$U1 $C} "\tfcmp.ZTR\tAL,AR\n";
'CMP' R[df], FLTDBL881 {$U1 $C} "\tfcmp.ZTR\tAL,AR\n";
#'CMP' R[df], CVSLAWD {$U1 $C} "\tfcmp.ZTR\tAL,AR\n";
#'STAR'[d] AWD[p] {$U1 $1 $<} "\tfmov.d\tAL,A1\n";
#'STAR'[f] AWD[p] {$U1 $1 $<} "\tfmov.s\tAL,A1\n";
LAWDnC[f] {$U1 $< $1} "RR!1\tfmov.ZT.\tAR,A1\n";
DAWD881 {$U1 $< $1} "RR!1\tfmov.ZT.\tAR,A1\n";
LAWDnC[f] {$U1 $C $< $1} "\tfmov.ZT.\tAR,A1\n";
DAWD881 {$U1 $C $< $1} "\tfmov.ZT.\tAR,A1\n";
#
# non M68881 double point ops
#
+[f] DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbadd%%\nZq\n\tjsr\tdbtofl%%\n" :3;
+[d] DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbadd%%\nZq" :3;
-[f] DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbsub%%\nZq\n\tjsr\tdbtofl%%\n" :3;
-[d] DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbsub%%\nZq" :3;
* DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbmul%%\nZq" :3;
/ DAWD[d], DAWD[d] {$A $1 $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbdiv%%\nZq" :3;
#
# WARNING: the =[d] instruction shares with result side.  It assumes no
#	   double indexing so the left registers will be pointer registers
#	   while the right registers may use both d0 and d1.
#
= DAWD[d], DAWD[d] {$A $< $> $R } "Y\tmov.l\tA-R,A-L\n\tmov.l\tZnAR,ZnAL\n";
#'STAR'[d] AWD[p] {$A $1 $<} "RL!1\tmov.l\tA-.,A1\nRL!1\tmov.l\tZnA.,A2\n";


# for the moment, to support both 16 and 32-bit machines, the
#	conversion ops for shorts are widened to longs

#
#			Convert to double.  Results in D0,D1
#
'CONV'[d] LAWD[f] {$A $1 $P $<   }      "RL!1\tmov.l\tAL,A1\n\tjsr\tfltodb%%\n";
'CONV'[d] LAWD[l] {$A $1 $<   }         "RL!1\tmov.l\tAL,A1\n\tjsr\tltodb%%\n" ;
'CONV'[d] LAWD[ul] {$A $1 $<   }        "RL!1\tmov.l\tAL,A1\n\tjsr\tultodb%%\n";
'CONV'[d] LAWD[s] {$A $1 $<}
	"RL!1\tmov.w\tAL,A1\n\text.l\tA1\n\tjsr\tltodb%%\n" ;
'CONV'[d] LAWD[us] {$A $1 $<}
	"\tmov.w\tAL,%d0\n\tswap.w\t%d0\n\tclr.w\t%d0\n\tswap.w\t%d0\n\tjsr\tultodb%%\n";
'CONV'[d] LAWD[c] {$A $1 $<}
@if @eakey@ != TRUE
	"\tmov.b\tAL,%d0\n\text.w\t%d0\n\text.l\t%d0\n\tjsr\tltodb%%\n" ;
@end
@if @eakey@ = TRUE
	"\tmov.b\tAL,%d0\n       extb.l     %d0\n       jsr\tltodb%%\n" ;
@end
'CONV'[d] LAWD[uc] {$A $1 $<}
	"\tmov.b\tAL,%d0\n\tand.l\t&0377,%d0\n\tjsr\tultodb%%\n";
'CONV'[f] DAWD[d] {$A $1 $< $l}		# Double to float result in D0
	"RL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbtofl%%\n";
'CONV'[csl] DAWD[d] {$A $1 $< $l}
	"RL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n	jsr\tdbtol%%\n" ;
'CONV'[ucusul] DAWD[d] {$A $1 $< $l}
	"RL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n	jsr\tdbtoul%%\n" ;
DAWD[d] {$A $< $1} "RR!1\tmov.l\tA-R,A1\nRR!1\tmov.l\tZnAR,A2\n";
DAWD[d] {$A $C $< $r}
	"RR!1\tmov.l\tA-R,A1\nRR!1\tmov.l\tZnAR,A2\n\tjsr\tdbtst%%\n\ttst.w\t%d0\n" ;
'UMINUS' DAWD[d]  {$1 $A $<}
	"RL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n\tjsr\tdbneg%%\n" ;
'CMP' DAWD[d], DAWD[d] {$A $C $< $> $l $r}
	"\tmov.l\tZnA-R,Z2\n\tmov.l\tAR,Z2\nRL!1\tmov.l\tA-L,A1\nRL!1\tmov.l\tZnAL,A2\n	jsr\tdbcmp%%\nZq\ttst.w\t%d0\n" :4;
'ARG' DAWDnC[d]  {$A $N $l} "	mov.l	ZnA-L,Z2\n	mov.l	AL,Z2\n" ;

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

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

'CONV'[lulcucsus] Cc {$1 $C} "	mov.l	AL,A1\n" :0;	# plus 1 for Cc
'CONV'[cucsus] LAWD[lul] {$1 $<   } "RL!1       mov.l   AL,A1\n" ;
'CONV'[cucsus] SAWD[sus] {$1 $<} "RL!1	mov.w	AL,A1\n" ;
'CONV'[cucsus] LAWD[lul] {$C $1 $<   } "        mov.l   AL,A1\n" ;
'CONV'[cucsus] SAWD[sus] {$C $1 $<} "	mov.w	AL,A1\n" ;
'CONV'[cucsuslul] LAWD[p] {$C $< $1   } "       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   } "        clr.w   A1\n    mov.b   AL,A1\n" :2;
'CONV'[sus] SEEA[uc] {$C $[ $1} "RL!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 $[}
@if @eakey@ != TRUE
	"RL!1\tmov.b\tAL,A1\n\text.w\tA1\n\text.l\tA1\n" :3;
@end
@if @eakey@ = TRUE
	"RL!1\tmov.b\tAL,A1\n\textb.l\tA1\n" :4;
@end
'CONV'[lul] R[uc] {$C $1 $<} "RL!1	mov.w	AL,A1\n	and.l	&0377,A1\n" :6;
'CONV'[lul] CAWDn2[uc] {$1   } "        mov.l   &0,A1\n mov.b   AL,A1\n" :4;
'CONV'[lul] SEEA[uc] {$C $[ $1} "RL!1	mov.b	AL,A1\n	and.l	&0377,A1\n" :6;
'CONV'[lul] SEEA[uc] {$1} "	mov.l	&0,A1\n	mov.b	AL,A1\n" :4;
'CONV'[lul] SAWD[s] {$C $1 $[} "RL!1	mov.w	AL,A1\n	ext.l	A1\n" :4;
'CONV'[lul] SAWD[us] {$1} "	mov.l	&0,A1\n	mov.w	AL,A1\n" :4;
'CONV'[lul] SAWD[us] {$1 $[} "RL!1\tmov.w\tAL,A1\n\tswap.w\tA1\n\tclr.w\tA1\n\tswap.w\tA1\n" :8;

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

'STARG' R  {2 $< $N} "ZS" ;
'STASG' R,R {1 $< $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" ;

# Convert to/from float
'CONV'[f] LAWD[l] {2 $1 $<   } "\tmov.l\tAL,Z2\n\tjsr\tltof%%\nZp" ;
'CONV'[f] LAWD[ul] {2 $1 $<   } "\tmov.l\tAL,Z2\n\tjsr\tultof%%\nZp" ;
'CONV'[f] LAWD[s] {2 $1 $<}
	"RL!1\tmov.w\tAL,A1\n\text.l\tA1\n\tmov.l\tA1,Z2\n\tjsr\tltof%%\nZp" ;
'CONV'[f] LAWD[us] {2 $1 $<}
"\tmov.w\tAL,%d0\n\tswap.w\t%d0\n\tclr.w\t%d0\n\tswap.w\t%d0\n\tmov.l\t%d0,Z2\n	jsr\tultof%%\nZp" ;
'CONV'[f] LAWD[c] {2 $1 $<}
@if @eakey@ != TRUE
"\tmov.b\tAL,%d0\n\text.w\t%d0\n\text.l\t%d0\n\tmov.l\t%d0,Z2\n\tjsr\tltof%%\nZp" ;
@end
@if @eakey@ = TRUE
"\tmov.b\tAL,%d0\n\textb.l\t%d0\n\tmov.l\t%d0,Z2\n\tjsr\tltof%%\nZp" ;
@end
'CONV'[f] LAWD[uc] {2 $1 $<}
     "\tmov.b\tAL,%d0\n\tand.l\t&0377,%d0\n\tmov.l\t%d0,Z2\n\tjsr\tultof%%\nZp";
'CONV'[cucsuslul] LAWD[f] {2 $1 $<   } "\tmov.l\tAL,Z2\n\tjsr\tftol%%\nZp" ;
'CONV'[f] R[f] {$U1 $1 $<   } "RL!1\tfmov.s\tAL,A1	#line 727\n" :0;
'CONV'[f] R[f] {$1 $<   } "RL!1\tmov.l\tAL,A1	#line 728\n" :0;
LAWD[f] {$1 $<   } "\tmov.l\tAR,A1\n";
LAWD[f] {2 $C $>   } "\tmov.l\tAR,Z2\n\tjsr\tfltst%%\nZp\ttst.w\t%d0\n" ;
'UMINUS' R[f]  {$1 2 $<} "\tmov.l\tAL,Z2\n\tjsr\tflneg%%\nZp" ;
'CMP' LAWD[f], LAWD[f] {2 $C $< $>      }
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflcmp%%\nZq\ttst.w\t%d0\n" :4;
'ARG' LAWD[f]  {$N   } "        mov.l   AL,Z2\n" ;

# floating point ops
# NOTE: all arithmetic is performed on doubles.
= LAWD[f], LAWD[f]         "\tmov.l\tAR,AL\n" ;
- LAWD[f], LAWD[f] {2 $1 $< $>      }
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflsub%%\nZq" :3;
* LAWD[f], LAWD[f] {2 $1 $< $>      }
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tflmul%%\nZq" :3;
/ LAWD[f], LAWD[f] {2 $1 $< $>      }
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tfldiv%%\nZq" :3;
+ LAWD[f], LAWD[f] {2 $1 $< $>      }
	"\tmov.l\tAR,Z2\n\tmov.l\tAL,Z2\n\tjsr\tfladd%%\nZq" :3;
