filename | src/tools/insparse.c |
changeset | 359:c588dce7ebde |
next | 420:e6f43dec3cf0 |
author | nkeynes |
date | Sat Sep 08 04:05:35 2007 +0000 (16 years ago) |
permissions | -rw-r--r-- |
last change | Handle video driver init failure cleanly (fallback to headless) Hookup shutdown for the GTK driver |
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 struct ruleset *parse_ruleset_file( FILE *f )
17 {
18 struct ruleset *rules = malloc( sizeof(struct ruleset ) );
19 char buf[512];
21 rules->rule_count = 0;
22 yyline = 0;
23 while( fgets( buf, sizeof(buf), f ) != NULL ) {
24 yyline++;
25 if( strncasecmp(buf, "registers", 9) == 0 ) {
26 parse_registers_block(buf, sizeof(buf), f);
27 } else if( buf[0] != '\0' && buf[0] != '#' && buf[0] != '\n' ) {
28 struct rule *rule;
29 char *p = buf;
30 rule = new_rule();
31 if( parse_rule( &p, rule ) != 0 ) {
32 free( rule );
33 } else {
34 rules->rules[rules->rule_count++] = rule;
35 }
36 }
37 }
38 return rules;
39 }
41 int parse_registers_block( char *buf, int buflen, FILE *f ) {
42 do {
43 if( strchr(buf, '}') != NULL ) {
44 break;
45 }
46 } while( fgets( buf, buflen, f ) != NULL );
47 }
49 /**
50 * Parse a single complete rule
51 * @return 0 on success, non-zero on failure
52 */
53 int parse_rule( char **str, struct rule *rule )
54 {
55 if( parse_bitstring( str, rule ) != 0 ) {
56 return -1;
57 }
59 /* consume whitespace in between */
60 while( isspace(**str) ) (*str)++;
61 if( **str == '\0' ) {
62 fprintf( stderr, "Unexpected end of file in rule on line %d\n", yyline );
63 return -1;
64 }
66 int result = parse_rule_format( str, rule );
67 if( result == 0 ) {
68 /* Reverse operand bit shifts */
69 int j;
70 for( j=0; j<rule->operand_count; j++ ) {
71 rule->operands[j].bit_shift =
72 rule->bit_count - rule->operands[j].bit_shift - rule->operands[j].bit_count;
73 }
74 if( **str == '!' ) {
75 (*str)++;
76 result = parse_operand_uses( str, rule );
77 }
78 }
80 return 0;
81 }
83 int parse_bitstring( char **str, struct rule *rule )
84 {
85 while( !isspace(**str) ) {
86 int ch = **str;
87 (*str)++;
88 switch( ch ) {
89 case '0':
90 rule->bits = rule->bits << 1;
91 rule->mask = (rule->mask << 1) | 1;
92 rule->bit_count++;
93 break;
94 case '1':
95 rule->bits = (rule->bits << 1) | 1;
96 rule->mask = (rule->mask << 1) | 1;
97 rule->bit_count++;
98 break;
99 case '(':
100 if( parse_bitoperand( str, rule ) != 0 ) {
101 return -1 ;
102 }
103 break;
104 default:
105 (*str)--;
106 fprintf( stderr, "Unexpected character '%c' in bitstring at line %d\n", ch, yyline );
107 return -1;
108 }
109 }
110 return 0;
111 }
113 int parse_bitoperand( char **str, struct rule *rule )
114 {
115 char *p = rule->operands[rule->operand_count].name;
116 char tmp[8];
118 if( rule->operand_count == MAX_OPERANDS ) {
119 fprintf( stderr, "Maximum operands/rule exceeded (%d) at line %d\n", MAX_OPERANDS, yyline );
120 return -1;
121 }
123 while( isalnum(**str) || **str == '_' ) {
124 *p++ = *(*str)++;
125 }
126 *p = '\0';
127 CONSUME_CHAR(':');
129 int size = parse_integer( str );
130 if( size == -1 ) {
131 return -1;
132 }
133 rule->operands[rule->operand_count].bit_count = size;
134 if( **str == 's' || **str == 'S' ) {
135 (*str)++;
136 rule->operands[rule->operand_count].is_signed = 1;
137 } else if( **str == 'u' || **str == 'U' ) {
138 (*str)++;
139 rule->operands[rule->operand_count].is_signed = 0;
140 }
141 if( **str == '<' ) {
142 (*str)++;
143 CONSUME_CHAR('<');
144 int lsl = parse_integer(str);
145 if( lsl == -1 ) {
146 return -1;
147 }
148 rule->operands[rule->operand_count].left_shift = lsl;
149 }
150 CONSUME_CHAR(')');
152 rule->operands[rule->operand_count].bit_shift = rule->bit_count;
153 rule->bit_count += size;
154 rule->bits = rule->bits << size;
155 rule->mask = rule->mask << size;
156 rule->operand_count++;
157 return 0;
158 }
160 int parse_integer( char **str )
161 {
162 uint32_t val = 0;
163 if( !isdigit(**str) ) {
164 fprintf(stderr, "Expected digit (0-9) but was '%c' at line %d\n", **str, yyline );
165 return -1;
166 }
167 do {
168 val = val * 10 + (**str - '0');
169 (*str)++;
170 } while( isdigit(**str) );
171 return val;
172 }
174 int parse_rule_format( char **str, struct rule *rule )
175 {
177 char tmp[64];
178 char *p = tmp;
179 while( **str != '\n' && **str != '\0' && **str != '!' ) {
180 *p++ = *(*str)++;
181 }
182 *p = '\0';
183 strcpy( rule->format, tmp );
185 return 0;
186 }
188 int parse_operand_uses( char **str, struct rule *rule )
189 {
191 }
193 void dump_ruleset( struct ruleset *rules, FILE *f )
194 {
195 int i, j;
196 fprintf( f, "Rulset: %d rules\n", rules->rule_count );
197 for( i=0; i<rules->rule_count; i++ ) {
198 struct rule *rule = rules->rules[i];
199 fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );
200 for( j=0; j<rule->operand_count; j++ ) {
201 fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,
202 rule->operands[j].is_signed ? "signed" : "unsigned",
203 rule->operands[j].bit_shift,
204 (1<<rule->operands[j].bit_count)-1 );
205 }
206 fprintf( f, "\n" );
207 }
208 }
210 void dump_rulesubset( struct ruleset *rules, int ruleidx[], int rule_count, FILE *f )
211 {
212 int i,j;
213 for( i=0; i<rule_count; i++ ) {
214 struct rule *rule = rules->rules[ruleidx[i]];
215 fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );
216 for( j=0; j<rule->operand_count; j++ ) {
217 fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,
218 rule->operands[j].is_signed ? "signed" : "unsigned",
219 rule->operands[j].bit_shift,
220 (1<<rule->operands[j].bit_count)-1 );
221 }
222 fprintf( f, "\n" );
223 }
224 }
.