014be56fb0
exactly equivalent and standard strchr() and strrchr() functions instead.
293 lines
7.1 KiB
Plaintext
293 lines
7.1 KiB
Plaintext
/* VAX descriptor table for ACK target optimizer,
|
|
*/
|
|
|
|
/* tunable constants-> */
|
|
|
|
MAXOP 4;
|
|
MAXLINELEN 50;
|
|
LABEL_STARTER 'I';
|
|
OPC_TERMINATOR ' ';
|
|
|
|
%%;
|
|
|
|
ZERO {strcmp(VAL,"$0") == 0};
|
|
ONE {strcmp(VAL,"$1") == 0};
|
|
M_ONE {strcmp(VAL,"$-1") == 0};
|
|
CONST {VAL[0] == '$'};
|
|
NUM,NUM1 {is_number(VAL)};
|
|
REG {is_register(VAL)};
|
|
SREG {is_scratchreg(VAL)};
|
|
LAB,LAB2 {VAL[0] == LABEL_STARTER};
|
|
A,B {no_side_effects(VAL) };
|
|
NO_INDEX {strchr(VAL, '[') == 0};
|
|
X,Y,LOG {TRUE};
|
|
|
|
%%;
|
|
|
|
movab 1(X),X -> incl X;
|
|
movab -1(X),X -> decl X;
|
|
|
|
movzbw ZERO,X -> clrw X;
|
|
movzbl ZERO,X -> clrl X;
|
|
movb ZERO,X -> clrb X;
|
|
movw ZERO,X -> clrw X;
|
|
movl ZERO,X -> clrl X;
|
|
cvtbw ZERO,X -> clrw X;
|
|
cvtww ZERO,X -> clrw X;
|
|
cvtbl ZERO,X -> clrl X;
|
|
cvtwl ZERO,X -> clrl X;
|
|
|
|
/* change 3-operand instructions to 2-operand instructions */
|
|
|
|
addw3 X,A,A -> addw2 X,A;
|
|
addl3 X,A,A -> addl2 X,A;
|
|
addf3 X,A,A -> addf2 X,A;
|
|
addd3 X,A,A -> addd2 X,A;
|
|
|
|
addw3 A,Y,A -> addw2 Y,A;
|
|
addl3 A,Y,A -> addl2 Y,A;
|
|
addf3 A,Y,A -> addf2 Y,A;
|
|
addd3 A,Y,A -> addd2 Y,A;
|
|
|
|
subw3 X,A,A -> subw2 X,A;
|
|
subl3 X,A,A -> subl2 X,A;
|
|
subf3 X,A,A -> subf2 X,A;
|
|
subd3 X,A,A -> subd2 X,A;
|
|
|
|
mulw3 X,A,A -> mulw2 X,A;
|
|
mull3 X,A,A -> mull2 X,A;
|
|
mulf3 X,A,A -> mulf2 X,A;
|
|
muld3 X,A,A -> muld2 X,A;
|
|
|
|
mulw3 A,Y,A -> mulw2 Y,A;
|
|
mull3 A,Y,A -> mull2 Y,A;
|
|
mulf3 A,Y,A -> mulf2 Y,A;
|
|
muld3 A,Y,A -> muld2 Y,A;
|
|
|
|
divw3 X,A,A -> divw2 X,A;
|
|
divl3 X,A,A -> divl2 X,A;
|
|
divf3 X,A,A -> divf2 X,A;
|
|
divd3 X,A,A -> divd2 X,A;
|
|
|
|
xorw3 X,A,A -> xorw2 X,A;
|
|
xorl3 X,A,A -> xorl2 X,A;
|
|
|
|
bisw3 X,A,A -> bisw2 X,A;
|
|
bisl3 X,A,A -> bisl2 X,A;
|
|
bisw3 A,Y,A -> bisw2 Y,A;
|
|
bisl3 A,Y,A -> bisl2 Y,A;
|
|
|
|
bicw3 X,A,A -> bicw2 X,A;
|
|
bicl3 X,A,A -> bicl2 X,A;
|
|
|
|
/* eliminate negative constants */
|
|
|
|
addw2 $-NUM,X -> subw2 $NUM,X;
|
|
addl2 $-NUM,X -> subl2 $NUM,X;
|
|
addw3 $-NUM,X,Y -> subw3 $NUM,X,Y;
|
|
addl3 $-NUM,X,Y -> subl3 $NUM,X,Y;
|
|
addw3 X,$-NUM,Y -> subw3 $NUM,X,Y;
|
|
addl3 X,$-NUM,Y -> subl3 $NUM,X,Y;
|
|
|
|
subw2 $-NUM,X -> addw2 $NUM,X;
|
|
subl2 $-NUM,X -> addl2 $NUM,X;
|
|
subw3 $-NUM,X,Y -> addw3 $NUM,X,Y;
|
|
subl3 $-NUM,X,Y -> addl3 $NUM,X,Y;
|
|
|
|
/* use special instructions */
|
|
|
|
addw2 ONE,X -> incw X;
|
|
addl2 ONE,X -> incl X;
|
|
subw2 ONE,X -> decw X;
|
|
subl2 ONE,X -> decl X;
|
|
|
|
addw2 M_ONE,X -> decw X;
|
|
addl2 M_ONE,X -> decl X;
|
|
subw2 M_ONE,X -> incw X;
|
|
subl2 M_ONE,X -> incl X;
|
|
|
|
/* careful! jbs has byte argument, jlbs has long argument, so be very careful
|
|
with indexed mode
|
|
*/
|
|
bitw $NUM,NO_INDEX : jneq LAB
|
|
{is_poweroftwo(NUM,LOG)}-> jbs $LOG,NO_INDEX,LAB;
|
|
bitl $NUM,NO_INDEX : jneq LAB
|
|
{is_poweroftwo(NUM,LOG)}-> jbs $LOG,NO_INDEX,LAB;
|
|
bitw $NUM,NO_INDEX : jeql LAB
|
|
{is_poweroftwo(NUM,LOG)}-> jbc $LOG,NO_INDEX,LAB;
|
|
bitl $NUM,NO_INDEX : jeql LAB
|
|
{is_poweroftwo(NUM,LOG)}-> jbc $LOG,NO_INDEX,LAB;
|
|
bitw ONE,NO_INDEX : jneq LAB -> jlbs NO_INDEX,LAB;
|
|
bitl ONE,A : jneq LAB -> jlbs A,LAB;
|
|
bitw ONE,NO_INDEX : jneq LAB -> jlbc NO_INDEX,LAB;
|
|
bitl ONE,A : jneq LAB -> jlbc A,LAB;
|
|
|
|
ashl $-NUM,A,REG : bicw2 $~NUM1,REG
|
|
{is_p2m1(NUM1,LOG)} -> extzv $NUM,$LOG,A,REG;
|
|
ashl $-NUM,A,REG : bicl2 $~NUM1,REG
|
|
{is_p2m1(NUM1,LOG)} -> extzv $NUM,$LOG,A,REG;
|
|
|
|
/* stack optimizations */
|
|
|
|
movl (sp)+,X : pushl X -> movl (sp),X;
|
|
tstw (sp)+ : movw X,-(sp) -> movw X,(sp);
|
|
tstl (sp)+ : movl X,-(sp) -> movl X,(sp);
|
|
tstw (sp)+ : clrw -(sp) -> clrw (sp);
|
|
tstl (sp)+ : clrl -(sp) -> clrl (sp);
|
|
tstw (sp)+ : movzbw X,-(sp) -> movzbw X,(sp);
|
|
tstl (sp)+ : movzbl X,-(sp) -> movzbl X,(sp);
|
|
tstw (sp)+ : cvtbw X,-(sp) -> cvtbw X,(sp);
|
|
tstl (sp)+ : cvtbl X,-(sp) -> cvtbl X,(sp);
|
|
tstw (sp)+ : tstw X -> movw X,(sp)+;
|
|
tstl (sp)+ : tstl X -> movl X,(sp)+;
|
|
tstl (sp)+ : pushl X -> movl X,(sp);
|
|
tstl (sp)+ : pushab X -> movab X,(sp);
|
|
tstl (sp)+ : pushaw X -> movaw X,(sp);
|
|
tstl (sp)+ : pushal X -> moval X,(sp);
|
|
tstl (sp)+ : pushaq X -> movaq X,(sp);
|
|
|
|
/* push constants */
|
|
|
|
clrw -(sp) : movw $NUM,-(sp) -> pushl $NUM;
|
|
clrw -(sp) : mnegw $NUM, -(sp) -> movzwl $-NUM,-(sp);
|
|
clrw -(sp) : movw X,-(sp) -> movzwl X,-(sp);
|
|
clrw -(sp) : cvtbw $NUM,-(sp) -> pushl $NUM;
|
|
clrw -(sp) : cvtbw CONST,-(sp) -> movzwl CONST,-(sp);
|
|
|
|
/* compare with zero */
|
|
|
|
cmpb X,ZERO -> tstb X;
|
|
cmpw X,ZERO -> tstw X;
|
|
cmpl X,ZERO -> tstl X;
|
|
cmpb ZERO,X : jneq LAB -> tstb X: jneq LAB;
|
|
cmpw ZERO,X : jneq LAB -> tstw X: jneq LAB;
|
|
cmpl ZERO,X : jneq LAB -> tstl X: jneq LAB;
|
|
|
|
cmpb ZERO,X : jeql LAB -> tstb X: jeql LAB;
|
|
cmpw ZERO,X : jeql LAB -> tstw X: jeql LAB;
|
|
cmpl ZERO,X : jeql LAB -> tstl X: jeql LAB;
|
|
|
|
cmpb ZERO,X : jgtr LAB -> tstb X: jlss LAB;
|
|
cmpw ZERO,X : jgtr LAB -> tstw X: jlss LAB;
|
|
cmpl ZERO,X : jgtr LAB -> tstl X: jlss LAB;
|
|
|
|
cmpb ZERO,X : jlss LAB -> tstb X: jgtr LAB;
|
|
cmpw ZERO,X : jlss LAB -> tstw X: jgtr LAB;
|
|
cmpl ZERO,X : jlss LAB -> tstl X: jgtr LAB;
|
|
|
|
cmpb ZERO,X : jgeq LAB -> tstb X: jleq LAB;
|
|
cmpw ZERO,X : jgeq LAB -> tstw X: jleq LAB;
|
|
cmpl ZERO,X : jgeq LAB -> tstl X: jleq LAB;
|
|
|
|
cmpb ZERO,X : jleq LAB -> tstb X: jgeq LAB;
|
|
cmpw ZERO,X : jleq LAB -> tstw X: jgeq LAB;
|
|
cmpl ZERO,X : jleq LAB -> tstl X: jgeq LAB;
|
|
|
|
/* compare with -1 */
|
|
|
|
cmpw M_ONE,SREG : jeql LAB -> incw SREG : jeql LAB;
|
|
cmpl M_ONE,SREG : jeql LAB -> incl SREG : jeql LAB;
|
|
cmpw M_ONE,SREG : jneq LAB -> incw SREG : jneq LAB;
|
|
cmpl M_ONE,SREG : jneq LAB -> incl SREG : jneq LAB;
|
|
|
|
/* eliminate redundant tests */
|
|
|
|
movw X,A : tstw A -> movw X,A;
|
|
movl X,A : tstl A -> movl X,A;
|
|
movw A,X : tstw A -> movw A,X;
|
|
movl A,X : tstl A -> movl A,X;
|
|
|
|
/* skip over jumps */
|
|
|
|
jeql LAB : jbr LAB2 : labdef LAB -> jneq LAB2 : labdef LAB;
|
|
jgeq LAB : jbr LAB2 : labdef LAB -> jlss LAB2 : labdef LAB;
|
|
jgtr LAB : jbr LAB2 : labdef LAB -> jleq LAB2 : labdef LAB;
|
|
jlss LAB : jbr LAB2 : labdef LAB -> jgeq LAB2 : labdef LAB;
|
|
jleq LAB : jbr LAB2 : labdef LAB -> jgtr LAB2 : labdef LAB;
|
|
jneq LAB : jbr LAB2 : labdef LAB -> jeql LAB2 : labdef LAB;
|
|
|
|
/* Register propagation */
|
|
|
|
movl REG,A : ANY *A -> movl REG,A : ANY (REG);
|
|
movl REG,A : ANY *A,X -> movl REG,A : ANY (REG),X;
|
|
movl REG,A : ANY X,*A -> movl REG,A : ANY X,(REG);
|
|
movl REG,A : ANY *A,X,Y -> movl REG,A : ANY (REG),X,Y;
|
|
movl REG,A : ANY X,*A,Y -> movl REG,A : ANY X,(REG),Y;
|
|
movl REG,A : ANY X,Y,*A -> movl REG,A : ANY X,Y,(REG);
|
|
|
|
/* convert floats, doubles */
|
|
cvtlf X,A : cvtfd A,A -> cvtld X,A;
|
|
cvtdf A,B : cvtfd B,A -> cvtdf A,B;
|
|
|
|
%%;
|
|
|
|
/* Auxiliary routines: */
|
|
|
|
int is_number(s)
|
|
register char *s;
|
|
{
|
|
while (*s >= '0' && *s <= '9') s++;
|
|
return *s == '\0';
|
|
}
|
|
|
|
int is_poweroftwo(s,t)
|
|
char *s,*t;
|
|
{
|
|
long arg, pow;
|
|
register int i;
|
|
|
|
arg = atol(s);
|
|
pow = 1;
|
|
i = 0;
|
|
while (pow > 0) {
|
|
if (pow == arg) {
|
|
sprintf(t,"%d",i);
|
|
return 1;
|
|
}
|
|
pow <<= 1;
|
|
i++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int is_p2m1(s,t)
|
|
char *s,*t;
|
|
{
|
|
long arg;
|
|
char buf[MAXLINELEN];
|
|
|
|
arg = atol(s)+1;
|
|
sprintf(buf,"%ld",arg);
|
|
return is_poweroftwo(buf,t);
|
|
}
|
|
|
|
int no_side_effects(s)
|
|
register char *s;
|
|
{
|
|
|
|
for(;;) {
|
|
switch(*s++) {
|
|
case '\0': return TRUE;
|
|
case '-': if (*s == '(') return FALSE; break;
|
|
case ')': if (*s == '+') return FALSE; break;
|
|
}
|
|
}
|
|
/* NOTREACHED */
|
|
}
|
|
|
|
int is_register(s)
|
|
register char *s;
|
|
{
|
|
if (*s++ == 'r' && *s >= '0' && *s <= '9') {
|
|
if (*s++ == '1' && (*s == '0' || *s == '1')) s++;
|
|
return *s == '\0';
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
int is_scratchreg(s)
|
|
register char *s;
|
|
{
|
|
return *s++ == 'r' && *s >= '0' && *s++ <= '3' && *s == '\0';
|
|
}
|