V8/usr/src/cmd/ccom/vax/stin

SHAPES
#	basic shapes
F:	'FREE';
N:	'NAME'	:2;
T:	'TEMP'	:1;
A:	'AUTO'	:1;
P:	'PARAM'	:1;
CC:	'CC';
R:	'REG':0;

#	constants
C:	:4;
Cna:	NONAME :4;
C0:	CONVAL 0 :0;
C1:	CONVAL 1 :0;
C2:	CONVAL 2 :0;
C3:	CONVAL 3 :0;
C4:	CONVAL 4 :0;
C8:	CONVAL 8 :0;

CR: C, R;

#	more complicated address modes

SOREG: *(R+C):1,  *R:1 , *(R-Cna) :1;
AWD: SOREG,R,T,N,C,P,A;
# indirect addresses
INDIR: *N:3, *T:3, *SOREG:3, *P:3, *A:3;
IAWD: AWD, INDIR;
# char addresses, short addresses, long addresses, double addresses
#	(auto decrement, auto increment, indexed, double index, and IAWD)
CADRS: R + AWD;
SADRS: ((R<<C1) + AWD), ('UAND'(AWD))+(R<<C1);
LADRS: ((R<<C2) + AWD), ('UAND'(AWD))+(R<<C2);
DADRS: ((R<<C3) + AWD), ('UAND'(AWD))+(R<<C3);
CAWD: *(R -= C1), *(R ++ C1), *( R + AWD ), IAWD ;
SAWD: *(R -= C2), *(R ++ C2), *((R<<C1)+AWD), *(('UAND'(AWD))+(R<<C1)), IAWD ;
LAWD: *(R -= C4), *(R ++ C4), *((R<<C2)+AWD), *(('UAND'(AWD))+(R<<C2)), IAWD ;
DAWD: *(R -= C8), *(R ++ C8), *((R<<C3)+AWD), *(('UAND'(AWD))+(R<<C3)), IAWD ;
SFLD: 'FLD' IAWD;
SCC: 'CONV' CAWD[c];
SCUC: 'CONV' CAWD[uc];
SCCUC: SCC, SCUC;
SCS: 'CONV' SAWD[s];
SCUS: 'CONV' SAWD[us];
SCSUS: SCS, SCUS;
SFLT: 'CONV' LAWD[f], LAWD[f];
CDAWD: 'CONV' DAWD[d], DAWD[d];

OPCODES
# default cost - can we make costing more accurate?
#	current method: add 1 for each opcode and 1 for each operand
DCOST  :3;

C0	{$N}	"":0;

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

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

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

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

'CALL' C,F {$A $< $1} "	calls	Zc,CL\n" ;
'CALL' R,F {$A $< $1} "	calls	Zc,(AL)\n" ;

'UCALL' C {$A $1} "	calls	$0,CL\n" ;
'UCALL' R {$A $< $1} "	calls	$0,(AL)\n" ;

= LAWD[p], CADRS {$L} "	movab	ZM,AL\n" ;
= LAWD[p], SADRS {$L} "	movaw	ZM,AL\n" ;
= LAWD[p], LADRS {$L} "	moval	ZM,AL\n" ;
= LAWD[p], DADRS {$L} "	movad	ZM,AL\n" ;

= CAWD[cuc],  C0 {$R} "	clrb	AL\n" :2;
= CAWD[cuc],  C0 {$L} "	clrb	AL\n" :2;
= CAWD[cuc], CR {$L}	"RL!R	movb	AR,AL\n" ;
= CAWD[cuc], CR {$R $C}	"	movb	AR,AL\n" ;
= CAWD[cuc], CAWD[cuc] {$L}	"	movb	AR,AL\n" ;
= CAWD[cuc], CAWD[cuc] {$R $C}	"	movb	AR,AL\n" ;

= SAWD[sus],  C0 {$R} "	clrw	AL\n" :2;
= SAWD[sus],  C0 {$L} "	clrw	AL\n" :2;
= SAWD[sus], SCC {$L $C}	"	cvtbw	AR,AL\n" ;
= SAWD[sus], SCUC {$L $C}	"	movzbw	AR,AL\n" ;
= SAWD[sus], CR {$L}	"RL!R	movw	AR,AL\n" ;
= SAWD[sus], CR {$R $C}	"	movw	AR,AL\n" ;
= SAWD[sus], SAWD[sus] {$L}	"	movw	AR,AL\n" ;
= SAWD[sus], SAWD[sus] {$R $C}	"	movw	AR,AL\n" ;

= LAWD[iuip], SCC {$L $C}	"	cvtbl	AR,AL\n" ;
= LAWD[iuip], SCUC {$L $C}	"	movzbl	AR,AL\n" ;
= LAWD[iuip], SCS {$L $C}	"	cvtwl	AR,AL\n" ;
= LAWD[iuip], SCUS {$L $C}	"	movzwl	AR,AL\n" ;
= LAWD[iuip],  C0 {$R} "	clrl	AL\n" ;
= LAWD[iuip],  C0 {$L} "	clrl	AL\n" ;
= LAWD[iuip], CR {$L} "RL!R	movl	AR,AL\n" ;
= LAWD[iuip], CR {$R $C} "	movl	AR,AL\n" ;
= LAWD[iuip], LAWD[iuip] {$L} "RL!R	movl	AR,AL\n" ;
= LAWD[iuip], LAWD[iuip] {$R $C} "	movl	AR,AL\n" ;

= SFLD[], LAWD[] { $R } "	insv	AR,$HL,$SL,AL\n" :5;
= LAWD[isc], SFLD[] {$L} "	extv	$HR,$SR,AR,AL\n" :5;
= LAWD[uiusuc], SFLD[] {$L} "	extzv	$HR,$SR,AR,AL\n" :5;

C0[iuisuspcuc] {$1} "	clrl	A1\n" :2;

# why not AL ??
CAWD[cuc] {$C} "	tstb	AR\n" :2;
SAWD[sus] {$C} "	tstw	AR\n" :2;
LAWD[iuip] {$C} "	tstl	AR\n" :2;
LAWD[f] {$C}  	"	tstf	AR\n" :2;
DAWD[d] {$C}   	"	tstd	AR\n" :2;
CAWD[cuc] {$> $1} "RR!1	movb	AR,A1\n" :3;
CAWD[cuc] {$> $1 $C} "	movb	AR,A1\n" :3;
SAWD[sus] {$> $1} "RR!1	movw	AR,A1\n" :3;
SAWD[sus] {$> $1 $C} "	movw	AR,A1\n" :3;
LAWD[iuip] {$> $1} "RR!1	movl	AR,A1\n" :3;
LAWD[iuip] {$> $1 $C} "	movl	AR,A1\n" :3;
LAWD[f]  {$> $1} "	movf	AR,A1\n" :3;
LAWD[f]  {$> $1 $C} "RR!1	movf	AR,A1\n" :3;
DAWD[d]  {$> $P $1} "	movd	AR,A1\n" :3;
DAWD[d]  {$> $P $1 $C} "RR!1	movd	AR,A1\n" :3;

'FLD' IAWD[isc] {$< $1} "	extv	$H.,$S.,AL,A1\n" :5;
'FLD' IAWD[uiusuc] {$< $1} "	extzv	$H.,$S.,AL,A1\n" :5;

'ARG' LAWD[iuip]  {$N} "	pushl	AL\n" :2;
'ARG' C 	 {$N} "	pushl	AL\n" :2;
'ARG' SCS  {$N} "	cvtwl	AL,-(sp)\n" ;
'ARG' SCC  {$N} "	cvtbl	AL,-(sp)\n" ;
'ARG' SCUS  {$N} "	movzwl	AL,-(sp)\n" ;
'ARG' SCUC  {$N} "	movzbl	AL,-(sp)\n" ;
'ARG' LAWD[f] "	cvtfd	AL,-(sp)\n" ;
'ARG' DAWD[d] "	movd	AL,-(sp)\n" ;

# comparison opcodes
#	"complex" comparisons - circumvent CONV nodes
# these phantom conversions should be removed in optim(), where allowed
#'CMP' SCCUC, Cuc[iui] {$C} "	cmpb	AL,AR\n" ;
#'CMP' SCCUC, R {$C} "	cmpb	AL,AR\n" ;

'CMP' CAWD[cuc], CAWD[cuc] {$C} "	cmpb	AL,AR\n" ;
#risky--used to be Cus on rhs
'CMP' SAWD[sus], C {$C} "	cmpw	AL,AR\n" ;
'CMP' SAWD[sus], R {$C} "	cmpw	AL,AR\n" ;
'CMP' SAWD[sus], SAWD[sus] {$C} "	cmpw	AL,AR\n" ;
'CMP' SFLT, SFLT {$C} "	cmpf	AL,AR\n" ;

#	"simple" comparisons - actually appear in tree
'CMP' LAWD[iuip], LAWD[iuip] {$C} "	cmpl	AL,AR\n" ;
'CMP' DAWD[d], DAWD[d] {$C} "	cmpd	AL,AR\n" ;

# unary minus
'UMINUS' LAWD[iuip] {$< $1} "	mnegl	AL,A1\n" ;
'UMINUS' DAWD[d] {$P $< $1} "	mnegd	AL,A1\n" ;

# compute addresses of automatics and parameters
'UAND' A {$1} "	moval	AL,A1\n" ;
'UAND' P {$1} "	moval	AL,A1\n" ;
'UAND' T {$1} "	moval	AL,A1\n" ;

# second operand of ++ and -- is the constant to be added or subtracted
# could play some games here with condition codes, since I think that
# inc doesn't change them...
++ CAWD[c], C1 {$1} "F	cvtbl	A-L,A1\n	incb	AL\n" :2;
++ CAWD[uc], C1 {$1} "F	movzbl	A-L,A1\n	incb	AL\n" :2;
++ CAWD[c], C {$1} "F	cvtbl	A-L,A1\n	addb2	AR,AL\n" ;
++ CAWD[uc], C {$1} "F	movzbl	A-L,A1\n	addb2	AR,AL\n" ;
++ SAWD[s], C1 {$1} "F	cvtwl	A-L,A1\n	incw	AL\n" :2;
++ SAWD[us], C1 {$1} "F	movzwl	A-L,A1\n	incw	AL\n" :2;
++ SAWD[s], C {$1} "F	cvtwl	A-L,A1\n	addw2	AR,AL\n" ;
++ SAWD[us], C {$1} "F	movzwl	A-L,A1\n	addw2	AR,AL\n" ;
++ LAWD[iuip], C1 {$1} "F	movl	A-L,A1\n	incl	AL\n" ;
++ LAWD[iuip], C {$1} "F	movl	A-L,A1\n	addl2	AR,AL\n" ;

-- CAWD[c], C1 {$1} "F	cvtbl	A-L,A1\n	decb	AL\n" :2;
-- CAWD[uc], C1 {$1} "F	movzbl	A-L,A1\n	decb	AL\n" :2;
-- CAWD[c], C {$1} "F	cvtbl	A-L,A1\n	subb2	AR,AL\n" ;
-- CAWD[uc], C {$1} "F	movzbl	A-L,A1\n	subb2	AR,AL\n" ;
-- SAWD[s], C1 {$1} "F	cvtwl	A-L,A1\n	decw	AL\n" :2;
-- SAWD[us], C1 {$1} "F	movzwl	A-L,A1\n	decw	AL\n" :2;
-- SAWD[s], C {$1} "F	cvtwl	A-L,A1\n	subw2	AR,AL\n" ;
-- SAWD[us], C {$1} "F	movzwl	A-L,A1\n	subw2	AR,AL\n" ;
-- LAWD[iuip], C1 {$1} "F	movl	A-L,A1\n	decl	AL\n" :2;
-- LAWD[iuip], C {$1} "F	movl	A-L,A1\n	subl2	AR,AL\n" ;

# & SAWD[susp], C {$C} "	bit	AL,AR\n" ;
# * R[susp], SAWD[susp] {$< $>  $2} "RL!1RL!2\tmov\tAL,A2\nRL!1\tmul\tAR,A2\nRL=1\tmul\tAR,AL\n" ;
# % SAWD[susp], SAWD[susp] {$<  $2} "RL!2	mov\tAL,r1\nZV\tdiv\tAR,r0\n" ;
# / SAWD[susp], SAWD[susp] {$< 2 $1} "RL!2\tmov\tAL,r1\nZV\tdiv\tAR,r0\n" ;

+= CAWD[cuc], C1 {$L $C} "	incb	AL\n" :2;
+= SAWD[sus], C1 {$L $C} "	incw	AL\n" :2;
+= LAWD[iuip], C1 {$L $C} "	incl	AL\n" :2;
+= LAWD[iuip], LAWD[iuip] {$L $C} "	addl2	AR,AL\n" ;

-= CAWD[cuc], C1 {$L $C} "	decb	AL\n" :2;
-= SAWD[sus], C1 {$L $C} "	decw	AL\n" :2;
-= LAWD[iuip], C1 {$L $C} "	decl	AL\n" :2;
-= LAWD[iuip], LAWD[iuip] {$L $C} "	subl2	AR,AL\n" ;

|= LAWD[iuip], LAWD[iuip] {$L $C} "	bisl2	AR,AL\n" ;

&= LAWD[iuip], Cna {$L $C} "	bicl2	Zk,AL\n" ;
&= LAWD[iuip], LAWD[iuip] {$L 1 $C} "	mcoml	AR,A1\n	bicl2	A1,AL\n" :6;

^= LAWD[iuip], LAWD[iuip] {$L $C} "	xorl2	AR,AL\n" ;

# right operand must be CAWD due to VAX operand typing
<<= LAWD[iuip], CAWD[iuip]  "	ashl	AR,A-L,AL\n" ;
<< LAWD[iuip], CAWD[iuip] {$1 $> $<}  "	ashl	AR,AL,A1\n" ;

>>= LAWD[i], LAWD[iuip]  {$L 1 $>} "	mnegl	AR,A1\n	ashl	A1,A-L,AL\n" :7;
>> LAWD[i], LAWD[iuip]  {$1 $>} "	mnegl	AR,A1\n	ashl	A1,AL,A1\n" :7;
# left operand must be IAWD due to VAX operand typing
>>= IAWD[i], C  {$L} "	extv	AR,ZU,A-L,AL\n" :5;
>> IAWD[i], C  {$1 $>} "	extv	AR,ZU,AL,A1\n" :5;

>>= IAWD[uip],CAWD[iuip] {$L 1 $C}"\tsubl3\tA-R,$32,A1\n\textzv\tAR,A1,A-L,AL\n":9;
>> IAWD[uip], CAWD[iuip] {$1 $C} "\tsubl3\tA-R,$32,A1\n\textzv\tAR,A1,AL,A1\n":9;
>>= IAWD[uip], C  {$L} "	extzv	AR,ZU,A-L,AL\n" :5;
>> IAWD[uip], C  {$1 $>} "	extzv	AR,ZU,AL,A1\n" :5;

# convert characters to other types
'CONV' [sus] CAWD[uc] {$< $1 $C} "	movzbw	AL,A1\n" ;
'CONV' [iuip] CAWD[uc] {$< $1 $C} "	movzbl	AL,A1\n" ;
'CONV' [sus] CAWD[c]  {$< $1 $C} "	cvtbw	AL,A1\n" ;
'CONV' [iuip] CAWD[c]  {$< $1 $C} "	cvtbl	AL,A1\n" ;
'CONV' [f] CAWD[uc]  {$< $1 $C} "\tmovzbl\tAL,A1\n\tcvtlf\tA1,A1\n" :6;
'CONV' [d] CAWD[uc]  {$< $P $1 $C} "\tmovzbl\tAL,A1\n\tcvtld\tA1,A1\n" :6;
'CONV' [f] CAWD[c]  {$< $1 $C}   "	cvtbf	AL,A1\n" ;
'CONV' [d] CAWD[c]  {$< $P $1 $C}   "	cvtbd	AL,A1\n" ;

# convert short to other types
'CONV' [cuc] SAWD[sus]  {$< $1} "RL!1	movw	AL,A1\n" ;
'CONV' [cuc] SAWD[sus]  {$< $1 $C} "	movw	AL,A1\n" ;
'CONV' [iuip] SAWD[s]  {$< $1 $C} "	cvtwl	AL,A1\n" ;
'CONV' [iuip] SAWD[us]  {$< $1 $C} "	movzwl	AL,A1\n" ;
'CONV' [f] SAWD[us]  {$< $1 $C} "\tmovzwl\tAL,A1\n\tcvtlf\tA1,A1\n" :6;
'CONV' [d] SAWD[us]  {$< $P $1 $C} "\tmovzwl\tAL,A1\n\tcvtld\tA1,A1\n" :6;
'CONV' [f] SAWD[s]  {$< $1 $C}  "	cvtwf	AL,A1\n" ;
'CONV' [d] SAWD[s]  {$< $P $1 $C}  "	cvtwd	AL,A1\n" ;

# convert integer (long values) to other types
'CONV' [cucsusiuip] LAWD[iuip]  {$< $1} "RL!1	movl	AL,A1\n" ;
'CONV' [cucsusiuip] LAWD[iuip]  {$< $1 $C} "	movl	AL,A1\n" ;
#?? need conversion for unsigned to [fd].  cvtl_ won't work correctly
#use cvtl_ for unsigned for now
'CONV' [f] LAWD[iuip]  {$< $1 $C} "	cvtlf	AL,A1\n" ;
'CONV' [d] LAWD[iuip]  {$< $1 $P $C} "	cvtld	AL,A1\n" ;

# convert floating to other types
'CONV' [cuc] LAWD[f]  {$< $1 $C} "	cvtfb	AL,A1\n" ;
'CONV' [sus] LAWD[f]  {$< $1 $C} "	cvtfw	AL,A1\n" ;
'CONV' [iuip] LAWD[f]  {$< $1 $C} "	cvtfl	AL,A1\n" ;
'CONV' [d] LAWD[f]  {$< $1 $P $C} "	cvtfd	AL,A1\n" ;

# convert double to other types
'CONV' [cuc] DAWD[d]  {$< $1 $C} "	cvtdb	AL,A1\n" ;
'CONV' [sus] DAWD[d]  {$< $1 $C} "	cvtdw	AL,A1\n" ;
'CONV' [iuip] DAWD[d]  {$< $1 $C} "	cvtdl	AL,A1\n" ;
'CONV' [f] DAWD[d]  {$< $1 $C} "	cvtdf	AL,A1\n" ;


# structure manipulation
#	movc3 blows regs r0 - r5, so ask for all temps
'STARG' AWD {$A $< $> $N} "	subl2	ZT,sp\nZS" ;
'STASG' AWD, AWD {$A $> $L} "ZS" ;

'INIT' [cuc] C  {$N} "	.byte	CL\n" ;
'INIT' [sus] C  {$N} "	.word	CL\n" ;
'INIT' [iuip] C  {$N} "	.long	CL\n" ;

= DAWD[d], DAWD[d] {$L} "RL!R	movd	AR,AL\n" ;
= DAWD[d], DAWD[d] {$R $C} "	movd	AR,AL\n" ;
= LAWD[f], LAWD[f] {$R} "	movl	AR,AL\n" ;
= LAWD[f], LAWD[f] {$C}	"	movf	AR,AL\n" ;
= LAWD[f], CDAWD {$R $C} "	cvtdf	AR,AL\n" ;

# integer opcodes
#	how about two-address opcodes, such as
#	+ LAWD[ip], R[ip] {$R} "	addl2	AL,AR\n" ;
# is someone smart enough to commute this if necessary??
+ LAWD[iuip], LAWD[iuip] {$1 $< $>} "	addl3	AL,AR,A1\n" :4;
- LAWD[iuip], LAWD[iuip] {$1 $< $>} "	subl3	AR,AL,A1\n" :4;
* LAWD[iuip], LAWD[iuip] {$< $> $1} "	mull3	AR,AL,A1\n" :4;
/ LAWD[ip], LAWD[ip] {$< $> $1} "	divl3	AR,AL,A1\n" :4;
/ LAWD[iui], LAWD[iui] {$A $1 $<} "\tpushl\tAR\n\tpushl\tAL\n\tcalls\t$2,udiv\n" :11;
~ LAWD[iuip] {$1 $< $C} "	mcoml	AL,A1\n" ;
| LAWD[iuip], LAWD[iuip] {$1 $< $> $C} "	bisl3	AR,AL,A1\n" :4;
& LAWD[iuip], LAWD[iuip] {$C} "	bitl	AR,AL\n" ;
# & LAWD[iuip], Cna {$C} "	bitl	AR,AL\n" ;
& LAWD[iuip], Cna {$1 $< $C} "	bicl3	Zk,AL,A1\n" :4;
& LAWD[iuip], LAWD[iuip] {$1 $> $C} "\tmcoml	AR,A1\n	bicl3	A1,AL,A1\n" :7;
% LAWD[ip], LAWD[ip] {$C $1 1} "\tdivl3\tA-R,A-L,A1\n\tmull2\tAR,A1\n\tsubl3\tA1,AL,A1\n" :11;
% LAWD[iui], LAWD[iui] {$A $1 $< $>} "\tpushl\tAR\n\tpushl\tAL\n\tcalls\t$2,urem\n" :11;
# following 3 address ops not included to reduce number of templates
# = LAWD[iuip], ( LAWD[iuip] + LAWD[iuip] ) "	addl3	A(RL),A(RR),AL\n" :4;
# = LAWD[iuip], ( LAWD[iuip] - LAWD[iuip] ) "	subl3	A(RR),A(RL),AL\n" :4;
# = LAWD[iuip], ( LAWD[iuip] | LAWD[iuip] ) "	bicl3	A(RL),A(RR),AL\n" :4;


# double opcodes
+ DAWD[d], DAWD[d] {$< $> $P $1 $C} "	addd3	AR,AL,A1\n" :4;
- DAWD[d], DAWD[d] {$< $> $P $1 $C} "	subd3	AR,AL,A1\n" :4;
* DAWD[d], DAWD[d] {$< $> $P $1 $C} "	muld3	AR,AL,A1\n" :4;
/ DAWD[d], DAWD[d] {$< $> $P $1 $C} "	divd3	AR,AL,A1\n" :4;

# double assignment opcodes
+= DAWD[d], DAWD[d] {$L $C} "	addd2	AR,AL\n" ;
-= DAWD[d], DAWD[d] {$L $C} "	subd2	AR,AL\n" ;
*= DAWD[d], DAWD[d] {$L $C} "	muld2	AR,AL\n" ;
/= DAWD[d], DAWD[d] {$L $C} "	divd2	AR,AL\n" ;

# float opcodes
+ LAWD[f], LAWD[f] {$< $> $1 $C} "	addf3	AR,AL,A1\n":3;
- LAWD[f], LAWD[f] {$< $> $1 $C} "	subf3	AR,AL,A1\n":3;
* LAWD[f], LAWD[f] {$< $> $1 $C} "	mulf3	AR,AL,A1\n":3;
/ LAWD[f], LAWD[f] {$< $> $1 $C} "	divf3	AR,AL,A1\n":3;

# float assignment opcodes
+= LAWD[f], LAWD[f] {$L $C} "	addf2	AR,AL\n";
-= LAWD[f], LAWD[f] {$L $C} "	subf2	AR,AL\n";
*= LAWD[f], LAWD[f] {$L $C} "	mulf2	AR,AL\n";
/= LAWD[f], LAWD[f] {$L $C} "	divf2	AR,AL\n";

# for the use of fortran only 

# 'GOTO' C  {$N} "	jbr	CL\n" ;
# 'GOTO' N[iui]  {$N} "	jmp	*UL\n" ;
# 'GOTO' N[suscucp]  {$N} "	jmp	*AL\n" ;