Search
lxdream.org :: lxdream/src/tools/insparse.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/tools/insparse.c
changeset 420:e6f43dec3cf0
prev359:c588dce7ebde
next561:533f6b478071
author nkeynes
date Tue Oct 09 08:12:29 2007 +0000 (16 years ago)
permissions -rw-r--r--
last change Fix compilation warnings
view annotate diff log raw
     1 #include <stdlib.h>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <ctype.h>
     5 #include "tools/gendec.h"
     7 #define CONSUME_CHAR(x) if( **str != x ) { fprintf( stderr, "Unexpected input character '%c', expected '%c' at line %d\n", **str, x, yyline ); return -1; } else { (*str)++; }
     8 static int yyline;
    10 struct rule *new_rule() {
    11     struct rule *rule = malloc( sizeof( struct rule ) );
    12     memset( rule, 0, sizeof( struct rule ) );
    13     return rule;
    14 }
    16 int parse_registers_block( char *buf, int buflen, FILE *f );
    17 int parse_rule( char **str, struct rule *rule );
    18 int parse_bitstring( char **str, struct rule *rule );
    19 int parse_bitoperand( char **str, struct rule *rule );
    20 int parse_integer( char **str );
    21 int parse_rule_format( char **str, struct rule *rule );
    22 int parse_operand_uses( char **str, struct rule *rule );
    26 struct ruleset *parse_ruleset_file( FILE *f ) 
    27 {
    28     struct ruleset *rules = malloc( sizeof(struct ruleset ) );
    29     char buf[512];
    31     rules->rule_count = 0;
    32     yyline = 0;
    33     while( fgets( buf, sizeof(buf), f ) != NULL ) {
    34 	yyline++;
    35 	if( strncasecmp(buf, "registers", 9) == 0 ) {
    36 	    parse_registers_block(buf, sizeof(buf), f);
    37 	} else if( buf[0] != '\0' && buf[0] != '#' && buf[0] != '\n' ) {
    38 	    struct rule *rule;
    39 	    char *p = buf;
    40 	    rule = new_rule();
    41 	    if( parse_rule( &p, rule ) != 0 ) {
    42 		free( rule );
    43 	    } else {
    44 		rules->rules[rules->rule_count++] = rule;
    45 	    }
    46 	}
    47     }
    48     return rules;
    49 }
    51 int parse_registers_block( char *buf, int buflen, FILE *f ) {
    52     do {
    53 	if( strchr(buf, '}') != NULL ) {
    54 	    break;
    55 	}
    56     } while( fgets( buf, buflen, f ) != NULL );
    57     return 0;
    58 }
    60 /**
    61  * Parse a single complete rule
    62  * @return 0 on success, non-zero on failure
    63  */
    64 int parse_rule( char **str, struct rule *rule ) 
    65 {
    66     if( parse_bitstring( str, rule ) != 0 ) {
    67 	return -1;
    68     }
    70     /* consume whitespace in between */
    71     while( isspace(**str) ) (*str)++;
    72     if( **str == '\0' ) {
    73 	fprintf( stderr, "Unexpected end of file in rule on line %d\n", yyline );
    74 	return -1;
    75     }
    77     int result = parse_rule_format( str, rule );
    78     if( result == 0 ) {
    79 	/* Reverse operand bit shifts */
    80 	int j;
    81 	for( j=0; j<rule->operand_count; j++ ) {
    82 	    rule->operands[j].bit_shift = 
    83 		rule->bit_count - rule->operands[j].bit_shift - rule->operands[j].bit_count;
    84 	}
    85 	if( **str == '!' ) {
    86 	    (*str)++;
    87 	    result = parse_operand_uses( str, rule );
    88 	}
    89     }
    91     return 0;
    92 }
    94 int parse_bitstring( char **str, struct rule *rule )
    95 {
    96     while( !isspace(**str) ) {
    97 	int ch = **str;
    98 	(*str)++;
    99 	switch( ch ) {
   100 	case '0':
   101 	    rule->bits = rule->bits << 1;
   102 	    rule->mask = (rule->mask << 1) | 1;
   103 	    rule->bit_count++;
   104 	    break;
   105 	case '1':
   106 	    rule->bits = (rule->bits << 1) | 1;
   107 	    rule->mask = (rule->mask << 1) | 1;
   108 	    rule->bit_count++;
   109 	    break;
   110 	case '(':
   111 	    if( parse_bitoperand( str, rule ) != 0 ) {
   112 		return -1 ;
   113 	    }
   114 	    break;
   115 	default:
   116 	    (*str)--;
   117 	    fprintf( stderr, "Unexpected character '%c' in bitstring at line %d\n", ch, yyline );
   118 	    return -1;
   119 	}
   120     }
   121     return 0;
   122 }
   124 int parse_bitoperand( char **str, struct rule *rule )
   125 {
   126     char *p = rule->operands[rule->operand_count].name;
   128     if( rule->operand_count == MAX_OPERANDS ) {
   129 	fprintf( stderr, "Maximum operands/rule exceeded (%d) at line %d\n", MAX_OPERANDS, yyline );
   130 	return -1;
   131     }
   133     while( isalnum(**str) || **str == '_' ) {
   134 	*p++ = *(*str)++;
   135     }
   136     *p = '\0';
   137     CONSUME_CHAR(':');
   139     int size = parse_integer( str );
   140     if( size == -1 ) {
   141 	return -1; 
   142     }
   143     rule->operands[rule->operand_count].bit_count = size;
   144     if( **str == 's' || **str == 'S' ) {
   145 	(*str)++;
   146 	rule->operands[rule->operand_count].is_signed = 1;
   147     } else if( **str == 'u' || **str == 'U' ) {
   148 	(*str)++;
   149 	rule->operands[rule->operand_count].is_signed = 0;
   150     }
   151     if( **str == '<' ) {
   152 	(*str)++;
   153 	CONSUME_CHAR('<');
   154 	int lsl = parse_integer(str);
   155 	if( lsl == -1 ) {
   156 	    return -1;
   157 	}
   158 	rule->operands[rule->operand_count].left_shift = lsl;
   159     }
   160     CONSUME_CHAR(')');
   162     rule->operands[rule->operand_count].bit_shift = rule->bit_count;
   163     rule->bit_count += size;
   164     rule->bits = rule->bits << size;
   165     rule->mask = rule->mask << size;
   166     rule->operand_count++;
   167     return 0;
   168 }
   170 int parse_integer( char **str )
   171 {
   172     uint32_t val = 0;
   173     if( !isdigit(**str) ) {
   174 	fprintf(stderr, "Expected digit (0-9) but was '%c' at line %d\n", **str, yyline );
   175 	return -1;
   176     }
   177     do {
   178 	val = val * 10 + (**str - '0');
   179 	(*str)++;
   180     } while( isdigit(**str) );
   181     return val;
   182 }
   184 int parse_rule_format( char **str, struct rule *rule )
   185 {
   187     char tmp[64];
   188     char *p = tmp;
   189     while( **str != '\n' && **str != '\0' && **str != '!' ) {
   190 	*p++ = *(*str)++;
   191     }
   192     *p = '\0';
   193     strcpy( rule->format, tmp );
   195     return 0;
   196 }
   198 int parse_operand_uses( char **str, struct rule *rule )
   199 {
   200     return 0;
   201 }
   203 void dump_ruleset( struct ruleset *rules, FILE *f ) 
   204 {
   205     int i, j;
   206     fprintf( f, "Rulset: %d rules\n", rules->rule_count );
   207     for( i=0; i<rules->rule_count; i++ ) {
   208 	struct rule *rule = rules->rules[i];
   209 	fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );
   210 	for( j=0; j<rule->operand_count; j++ ) {
   211 	    fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,
   212 		     rule->operands[j].is_signed ? "signed" : "unsigned", 
   213 		     rule->operands[j].bit_shift,
   214 		     (1<<rule->operands[j].bit_count)-1 );
   215 	}
   216 	fprintf( f, "\n" );
   217     }
   218 }
   220 void dump_rulesubset( struct ruleset *rules, int ruleidx[], int rule_count, FILE *f )
   221 {
   222     int i,j;
   223     for( i=0; i<rule_count; i++ ) {
   224 	struct rule *rule = rules->rules[ruleidx[i]];
   225 	fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );
   226 	for( j=0; j<rule->operand_count; j++ ) {
   227 	    fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,
   228 		     rule->operands[j].is_signed ? "signed" : "unsigned", 
   229 		     rule->operands[j].bit_shift,
   230 		     (1<<rule->operands[j].bit_count)-1 );
   231 	}
   232 	fprintf( f, "\n" );
   233     }
   234 }
.