138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			Text
		
	
	
	
	
	
| /* 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;
 | |
| }
 |