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)++; }
10 struct rule *new_rule() {
11 struct rule *rule = malloc( sizeof( struct rule ) );
12 memset( rule, 0, sizeof( struct rule ) );
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 )
28 struct ruleset *rules = malloc( sizeof(struct ruleset ) );
31 rules->rule_count = 0;
33 while( fgets( buf, sizeof(buf), f ) != NULL ) {
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' ) {
41 if( parse_rule( &p, rule ) != 0 ) {
44 rules->rules[rules->rule_count++] = rule;
51 int parse_registers_block( char *buf, int buflen, FILE *f ) {
53 if( strchr(buf, '}') != NULL ) {
56 } while( fgets( buf, buflen, f ) != NULL );
61 * Parse a single complete rule
62 * @return 0 on success, non-zero on failure
64 int parse_rule( char **str, struct rule *rule )
66 if( parse_bitstring( str, rule ) != 0 ) {
70 /* consume whitespace in between */
71 while( isspace(**str) ) (*str)++;
73 fprintf( stderr, "Unexpected end of file in rule on line %d\n", yyline );
77 int result = parse_rule_format( str, rule );
79 /* Reverse operand bit shifts */
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;
87 result = parse_operand_uses( str, rule );
94 int parse_bitstring( char **str, struct rule *rule )
96 while( !isspace(**str) ) {
101 rule->bits = rule->bits << 1;
102 rule->mask = (rule->mask << 1) | 1;
106 rule->bits = (rule->bits << 1) | 1;
107 rule->mask = (rule->mask << 1) | 1;
111 if( parse_bitoperand( str, rule ) != 0 ) {
117 fprintf( stderr, "Unexpected character '%c' in bitstring at line %d\n", ch, yyline );
124 int parse_bitoperand( char **str, struct rule *rule )
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 );
133 while( isalnum(**str) || **str == '_' ) {
139 int size = parse_integer( str );
143 rule->operands[rule->operand_count].bit_count = size;
144 if( **str == 's' || **str == 'S' ) {
146 rule->operands[rule->operand_count].is_signed = 1;
147 } else if( **str == 'u' || **str == 'U' ) {
149 rule->operands[rule->operand_count].is_signed = 0;
154 int lsl = parse_integer(str);
158 rule->operands[rule->operand_count].left_shift = lsl;
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++;
170 int parse_integer( char **str )
173 if( !isdigit(**str) ) {
174 fprintf(stderr, "Expected digit (0-9) but was '%c' at line %d\n", **str, yyline );
178 val = val * 10 + (**str - '0');
180 } while( isdigit(**str) );
184 int parse_rule_format( char **str, struct rule *rule )
189 while( **str != '\n' && **str != '\0' && **str != '!' ) {
193 strcpy( rule->format, tmp );
198 int parse_operand_uses( char **str, struct rule *rule )
203 void dump_ruleset( struct ruleset *rules, FILE *f )
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 );
220 void dump_rulesubset( struct ruleset *rules, int ruleidx[], int rule_count, FILE *f )
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 );
.