/* sparc desciptor table for ACK target optimizer */ MAXOP 3; OPC_TERMINATOR '\t'; %%; /* useful addressing modes-> */ NUM,NUM1,NUM2 {is_number(VAL) }; REG {VAL[0] == '%' }; A,B,X,Y,Z {TRUE }; REG_NO_O7 {VAL[0] == '%' && (VAL[1] != 'o' || VAL[2] != '7')}; NO_O7 {no_o7(VAL) }; %%; /* optimization patterns-> */ /* tricky because we cannot optimize an instruction that lives in a delay slot */ /* usage of delay slot: */ ANY X,Y,Z : st REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X,Y,Z : call A : st REG_NO_O7,NO_O7 ; ANY X,Y : st REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X,Y : call A : st REG_NO_O7,NO_O7 ; ANY X : st REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X : call A : st REG_NO_O7,NO_O7 ; ANY X,Y,Z : mov REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X,Y,Z : call A : mov REG_NO_O7,NO_O7 ; ANY X,Y : mov REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X,Y : call A : mov REG_NO_O7,NO_O7 ; ANY X : mov REG_NO_O7,NO_O7 : call A : nop {no_delay(ANY)} -> ANY X : call A : mov REG_NO_O7,NO_O7 ; ANY X,Y,Z : st REG,B : b A : nop {no_delay(ANY)} -> ANY X,Y,Z : b A : st REG,B ; ANY X,Y : st REG,B : b A : nop {no_delay(ANY)} -> ANY X,Y : b A : st REG,B ; ANY X : st REG,B : b A : nop {no_delay(ANY)} -> ANY X : b A : st REG,B ; /* inc/dec: */ ANY X,Y,Z : inc NUM,REG : dec NUM,REG {no_delay(ANY)} -> ANY X,Y,Z ; ANY X,Y : inc NUM,REG : dec NUM,REG {no_delay(ANY)} -> ANY X,Y ; ANY X : inc NUM,REG : dec NUM,REG {no_delay(ANY)} -> ANY X ; ANY X,Y,Z : inc 0,REG {no_delay(ANY)} -> ANY X,Y,Z ; ANY X,Y : inc 0,REG {no_delay(ANY)} -> ANY X,Y ; ANY X : inc 0,REG {no_delay(ANY)} -> ANY X ; ANY X,Y,Z : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && bigger(NUM,NUM1,NUM2)} -> ANY X,Y,Z : inc NUM2,REG ; ANY X,Y : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && bigger(NUM,NUM1,NUM2)} -> ANY X,Y : inc NUM2,REG ; ANY X : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && bigger(NUM,NUM1,NUM2)} -> ANY X : inc NUM2,REG ; ANY X,Y,Z : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && smaller(NUM,NUM1,NUM2)} -> ANY X,Y,Z : dec NUM2,REG ; ANY X,Y : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && smaller(NUM,NUM1,NUM2)} -> ANY X,Y : dec NUM2,REG ; ANY X : inc NUM,REG : dec NUM1,REG {no_delay(ANY) && smaller(NUM,NUM1,NUM2)} -> ANY X : dec NUM2,REG ; /* misc: */ ANY X,Y,Z : ld A,REG : ld A,REG1 {no_delay(ANY)} -> ANY X,Y,Z : ld A,REG : mov REG,REG1 ; ANY X,Y : ld A,REG : ld A,REG1 {no_delay(ANY)} -> ANY X,Y : ld A,REG : mov REG,REG1 ; ANY X : ld A,REG : ld A,REG1 {no_delay(ANY)} -> ANY X : ld A,REG : mov REG,REG1 ; ANY X,Y,Z : st REG,A : ld A,REG1 {no_delay(ANY)} -> ANY X,Y,Z : st REG,A : mov REG,REG1 ; ANY X,Y : st REG,A : ld A,REG1 {no_delay(ANY)} -> ANY X,Y : st REG,A : mov REG,REG1 ; ANY X : st REG,A : ld A,REG1 {no_delay(ANY)} -> ANY X : st REG,A : mov REG,REG1 ; %%; /* auxiliary routines: */ int is_number(s) register char *s; { while (*s != '\0') { if (*s < '0' || *s++ > '9') return FALSE; } return TRUE; } int bigger(s,s1,s2) char *s,*s1,*s2; { int n = atoi(s),n1 = atoi(s1); if (n >= n1) { sprintf(s2,"%d",n-n1); return TRUE; } return FALSE; } int smaller(s,s1,s2) char *s,*s1,*s2; { int n = atoi(s),n1 = atoi(s1); if (n < n1) { sprintf(s2,"%d",n1-n); return TRUE; } return FALSE; } int no_delay(s) char *s; { return s[0] != 'b' && s[0] != 'j' && s[0] != 'r' && s[1] != 'b' && s[0] != 'c'; } int no_o7(s) char *s; { for (;;) { while (*s && *s != '%') s++; if (*s) { if (*++s == 'o') { if (*++s == '7') return FALSE; } } else break; } return TRUE; }