Search
lxdream.org :: lxdream/src/tools/gendec.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/tools/gendec.c
changeset 736:a02d1475ccfd
prev561:533f6b478071
next824:016cda9d0518
author nkeynes
date Thu Aug 07 23:32:34 2008 +0000 (15 years ago)
permissions -rw-r--r--
last change Unroll first iteration of the bounding loop in ta_commit_polygon - more to
remove the compiler warnings than for performance really.
file annotate diff log raw
1.1 --- a/src/tools/gendec.c Tue Jan 01 05:08:38 2008 +0000
1.2 +++ b/src/tools/gendec.c Thu Aug 07 23:32:34 2008 +0000
1.3 @@ -50,13 +50,13 @@
1.4 * Find a mask that can be used to split up the given rules
1.5 */
1.6 uint32_t find_mask( struct ruleset *rules, int ruleidx[], int rule_count,
1.7 - uint32_t input_mask )
1.8 + uint32_t input_mask )
1.9 {
1.10 int i;
1.11 uint32_t mask = rules->rules[ruleidx[0]]->mask;
1.12
1.13 for( i=1; i<rule_count; i++ ) {
1.14 - mask = mask & rules->rules[ruleidx[i]]->mask;
1.15 + mask = mask & rules->rules[ruleidx[i]]->mask;
1.16 }
1.17
1.18 assert( (mask & input_mask) == input_mask ); /* input_mask should always be included in the mask */
1.19 @@ -68,9 +68,9 @@
1.20 int count = 0;
1.21
1.22 while( mask ) {
1.23 - if( mask&1 )
1.24 - count++;
1.25 - mask >>= 1;
1.26 + if( mask&1 )
1.27 + count++;
1.28 + mask >>= 1;
1.29 }
1.30 return 1<<count;
1.31 }
1.32 @@ -78,23 +78,23 @@
1.33 int get_bitshift_for_mask( uint32_t mask ) {
1.34 int shift = 0;
1.35 while( mask && !(mask&1) ) {
1.36 - shift++;
1.37 - mask >>= 1;
1.38 + shift++;
1.39 + mask >>= 1;
1.40 }
1.41 return shift;
1.42 }
1.43
1.44 void get_option_values_for_mask( uint32_t *options,
1.45 - uint32_t mask )
1.46 + uint32_t mask )
1.47 {
1.48 /* This could be a lot smarter. But it's not */
1.49 int i;
1.50 *options = 0;
1.51 for( i=1; i<=mask; i++ ) {
1.52 - if( (i & mask) > *options ) {
1.53 - options++;
1.54 - *options = (i&mask);
1.55 - }
1.56 + if( (i & mask) > *options ) {
1.57 + options++;
1.58 + *options = (i&mask);
1.59 + }
1.60 }
1.61 }
1.62
1.63 @@ -105,24 +105,24 @@
1.64
1.65 /* Determine number of spaces in first line of input */
1.66 for( i=0; isspace(action[i]); i++ ) {
1.67 - if( action[i] == '\n' ) {
1.68 - spaces = 0;
1.69 - text = &action[i+1];
1.70 - } else {
1.71 - spaces++;
1.72 - }
1.73 + if( action[i] == '\n' ) {
1.74 + spaces = 0;
1.75 + text = &action[i+1];
1.76 + } else {
1.77 + spaces++;
1.78 + }
1.79 }
1.80
1.81 needed -= spaces;
1.82 fprintf( f, "%*c", needed, ' ' );
1.83 for( i=0; text[i] != '\0'; i++ ) {
1.84 - fputc( text[i], f );
1.85 - if( text[i] == '\n' && text[i+1] != '\0' ) {
1.86 - fprintf( f, "%*c", needed, ' ' );
1.87 - }
1.88 + fputc( text[i], f );
1.89 + if( text[i] == '\n' && text[i+1] != '\0' ) {
1.90 + fprintf( f, "%*c", needed, ' ' );
1.91 + }
1.92 }
1.93 if( text[i-1] != '\n' ) {
1.94 - fprintf( f, "\n" );
1.95 + fprintf( f, "\n" );
1.96 }
1.97 }
1.98
1.99 @@ -130,96 +130,96 @@
1.100 {
1.101 int i;
1.102 if( action == NULL ) {
1.103 - fprintf( f, "%*cUNIMP(ir); /* %s */\n", depth*8, ' ', rule->format );
1.104 + fprintf( f, "%*cUNIMP(ir); /* %s */\n", depth*8, ' ', rule->format );
1.105 } else {
1.106 - fprintf( f, "%*c{ /* %s */", depth*8, ' ', rule->format );
1.107 - if( rule->operand_count != 0 ) {
1.108 - fprintf( f, "\n%*c", depth*8, ' ' );
1.109 - for( i=0; i<rule->operand_count; i++ ) {
1.110 - if( rule->operands[i].is_signed ) {
1.111 - fprintf( f, "int32_t %s = SIGNEXT%d", rule->operands[i].name, rule->operands[i].bit_count );
1.112 - } else {
1.113 - fprintf( f, "uint32_t %s = ", rule->operands[i].name );
1.114 - }
1.115 - if( rule->operands[i].bit_shift == 0 ) {
1.116 - fprintf( f, "(ir&0x%X)", (1<<(rule->operands[i].bit_count))-1 );
1.117 - } else {
1.118 - fprintf( f, "((ir>>%d)&0x%X)", rule->operands[i].bit_shift,
1.119 - (1<<(rule->operands[i].bit_count))-1 );
1.120 - }
1.121 - if( rule->operands[i].left_shift != 0 ) {
1.122 - fprintf( f, "<<%d", rule->operands[i].left_shift );
1.123 - }
1.124 - fprintf( f, "; " );
1.125 - }
1.126 - }
1.127 - fputs( "\n", f );
1.128 - if( action[0] != '\0' ) {
1.129 - fprint_indent( action, depth, f );
1.130 - }
1.131 - fprintf( f, "%*c}\n", depth*8, ' ' );
1.132 + fprintf( f, "%*c{ /* %s */", depth*8, ' ', rule->format );
1.133 + if( rule->operand_count != 0 ) {
1.134 + fprintf( f, "\n%*c", depth*8, ' ' );
1.135 + for( i=0; i<rule->operand_count; i++ ) {
1.136 + if( rule->operands[i].is_signed ) {
1.137 + fprintf( f, "int32_t %s = SIGNEXT%d", rule->operands[i].name, rule->operands[i].bit_count );
1.138 + } else {
1.139 + fprintf( f, "uint32_t %s = ", rule->operands[i].name );
1.140 + }
1.141 + if( rule->operands[i].bit_shift == 0 ) {
1.142 + fprintf( f, "(ir&0x%X)", (1<<(rule->operands[i].bit_count))-1 );
1.143 + } else {
1.144 + fprintf( f, "((ir>>%d)&0x%X)", rule->operands[i].bit_shift,
1.145 + (1<<(rule->operands[i].bit_count))-1 );
1.146 + }
1.147 + if( rule->operands[i].left_shift != 0 ) {
1.148 + fprintf( f, "<<%d", rule->operands[i].left_shift );
1.149 + }
1.150 + fprintf( f, "; " );
1.151 + }
1.152 + }
1.153 + fputs( "\n", f );
1.154 + if( action[0] != '\0' ) {
1.155 + fprint_indent( action, depth, f );
1.156 + }
1.157 + fprintf( f, "%*c}\n", depth*8, ' ' );
1.158 }
1.159 }
1.160
1.161 void split_and_generate( struct ruleset *rules, struct actionset *actions,
1.162 - int ruleidx[], int rule_count, int input_mask,
1.163 - int depth, FILE *f ) {
1.164 + int ruleidx[], int rule_count, int input_mask,
1.165 + int depth, FILE *f ) {
1.166 uint32_t mask;
1.167 int i,j;
1.168
1.169 if( rule_count == 0 ) {
1.170 - fprintf( f, "%*cUNDEF(ir);\n", depth*8, ' ' );
1.171 + fprintf( f, "%*cUNDEF(ir);\n", depth*8, ' ' );
1.172 } else if( rule_count == 1 ) {
1.173 - fprint_action( rules->rules[ruleidx[0]], actions->actions[ruleidx[0]], depth, f );
1.174 + fprint_action( rules->rules[ruleidx[0]], actions->actions[ruleidx[0]], depth, f );
1.175 } else {
1.176
1.177 - mask = find_mask(rules, ruleidx, rule_count, input_mask);
1.178 - if( mask == 0 ) { /* No matching mask? */
1.179 - fprintf( stderr, "Error: unable to find a valid bitmask (%d rules, %08X input mask)\n", rule_count, input_mask );
1.180 - dump_rulesubset( rules, ruleidx, rule_count, stderr );
1.181 - return;
1.182 - }
1.183 -
1.184 - /* break up the rules into sub-sets, and process each sub-set.
1.185 - * NB: We could do this in one pass at the cost of more complex
1.186 - * data structures. For now though, this keeps it simple
1.187 - */
1.188 - int option_count = get_option_count_for_mask( mask );
1.189 - uint32_t options[option_count];
1.190 - int subruleidx[rule_count];
1.191 - int subrule_count;
1.192 - int mask_shift = get_bitshift_for_mask( mask );
1.193 - int has_empty_options = 0;
1.194 - get_option_values_for_mask( options, mask );
1.195 -
1.196 - if( mask_shift == 0 ) {
1.197 - fprintf( f, "%*cswitch( ir&0x%X ) {\n", depth*8, ' ', mask );
1.198 - } else {
1.199 - fprintf( f, "%*cswitch( (ir&0x%X) >> %d ) {\n", depth*8, ' ',
1.200 - mask, mask_shift);
1.201 - }
1.202 - for( i=0; i<option_count; i++ ) {
1.203 - subrule_count = 0;
1.204 - for( j=0; j<rule_count; j++ ) {
1.205 - int match = rules->rules[ruleidx[j]]->bits & mask;
1.206 - if( match == options[i] ) {
1.207 - subruleidx[subrule_count++] = ruleidx[j];
1.208 - }
1.209 - }
1.210 - if( subrule_count == 0 ) {
1.211 - has_empty_options = 1;
1.212 - } else {
1.213 - fprintf( f, "%*ccase 0x%X:\n", depth*8+4, ' ', options[i]>>mask_shift );
1.214 - split_and_generate( rules, actions, subruleidx, subrule_count,
1.215 - mask|input_mask, depth+1, f );
1.216 - fprintf( f, "%*cbreak;\n", depth*8+8, ' ' );
1.217 - }
1.218 - }
1.219 - if( has_empty_options ) {
1.220 - fprintf( f, "%*cdefault:\n%*cUNDEF();\n%*cbreak;\n",
1.221 - depth*8+4, ' ', depth*8+8, ' ', depth*8 + 8, ' ' );
1.222 - }
1.223 - fprintf( f, "%*c}\n", depth*8, ' ' );
1.224 + mask = find_mask(rules, ruleidx, rule_count, input_mask);
1.225 + if( mask == 0 ) { /* No matching mask? */
1.226 + fprintf( stderr, "Error: unable to find a valid bitmask (%d rules, %08X input mask)\n", rule_count, input_mask );
1.227 + dump_rulesubset( rules, ruleidx, rule_count, stderr );
1.228 + return;
1.229 + }
1.230 +
1.231 + /* break up the rules into sub-sets, and process each sub-set.
1.232 + * NB: We could do this in one pass at the cost of more complex
1.233 + * data structures. For now though, this keeps it simple
1.234 + */
1.235 + int option_count = get_option_count_for_mask( mask );
1.236 + uint32_t options[option_count];
1.237 + int subruleidx[rule_count];
1.238 + int subrule_count;
1.239 + int mask_shift = get_bitshift_for_mask( mask );
1.240 + int has_empty_options = 0;
1.241 + get_option_values_for_mask( options, mask );
1.242 +
1.243 + if( mask_shift == 0 ) {
1.244 + fprintf( f, "%*cswitch( ir&0x%X ) {\n", depth*8, ' ', mask );
1.245 + } else {
1.246 + fprintf( f, "%*cswitch( (ir&0x%X) >> %d ) {\n", depth*8, ' ',
1.247 + mask, mask_shift);
1.248 + }
1.249 + for( i=0; i<option_count; i++ ) {
1.250 + subrule_count = 0;
1.251 + for( j=0; j<rule_count; j++ ) {
1.252 + int match = rules->rules[ruleidx[j]]->bits & mask;
1.253 + if( match == options[i] ) {
1.254 + subruleidx[subrule_count++] = ruleidx[j];
1.255 + }
1.256 + }
1.257 + if( subrule_count == 0 ) {
1.258 + has_empty_options = 1;
1.259 + } else {
1.260 + fprintf( f, "%*ccase 0x%X:\n", depth*8+4, ' ', options[i]>>mask_shift );
1.261 + split_and_generate( rules, actions, subruleidx, subrule_count,
1.262 + mask|input_mask, depth+1, f );
1.263 + fprintf( f, "%*cbreak;\n", depth*8+8, ' ' );
1.264 + }
1.265 + }
1.266 + if( has_empty_options ) {
1.267 + fprintf( f, "%*cdefault:\n%*cUNDEF();\n%*cbreak;\n",
1.268 + depth*8+4, ' ', depth*8+8, ' ', depth*8 + 8, ' ' );
1.269 + }
1.270 + fprintf( f, "%*c}\n", depth*8, ' ' );
1.271 }
1.272 }
1.273
1.274 @@ -229,15 +229,15 @@
1.275 int i;
1.276
1.277 for( i=0; i<rules->rule_count; i++ ) {
1.278 - ruleidx[i] = i;
1.279 + ruleidx[i] = i;
1.280 }
1.281
1.282 fputs( actions->pretext, f );
1.283 -
1.284 +
1.285 split_and_generate( rules, actions, ruleidx, rules->rule_count, 0, 1, f );
1.286
1.287 fputs( actions->posttext, f );
1.288 -
1.289 +
1.290 return 0;
1.291 }
1.292
1.293 @@ -248,12 +248,12 @@
1.294 fputs( "%%\n", f );
1.295
1.296 for( i=0; i<rules->rule_count; i++ ) {
1.297 - fprintf( f, "%s {: %s :}\n", rules->rules[i]->format,
1.298 - actions->actions[i] == NULL ? "" : actions->actions[i] );
1.299 + fprintf( f, "%s {: %s :}\n", rules->rules[i]->format,
1.300 + actions->actions[i] == NULL ? "" : actions->actions[i] );
1.301 }
1.302 fputs( "%%\n", f );
1.303 fputs( actions->posttext, f );
1.304 -
1.305 +
1.306 return 0;
1.307 }
1.308
1.309 @@ -265,87 +265,87 @@
1.310 /* Parse the command line */
1.311 while( (opt = getopt_long( argc, argv, option_list, longopts, NULL )) != -1 ) {
1.312 switch( opt ) {
1.313 - case 't':
1.314 - gen_mode = GEN_TEMPLATE;
1.315 - break;
1.316 - case 'o':
1.317 - out_filename = optarg;
1.318 - break;
1.319 - case 'h':
1.320 - usage();
1.321 - exit(0);
1.322 - }
1.323 + case 't':
1.324 + gen_mode = GEN_TEMPLATE;
1.325 + break;
1.326 + case 'o':
1.327 + out_filename = optarg;
1.328 + break;
1.329 + case 'h':
1.330 + usage();
1.331 + exit(0);
1.332 + }
1.333 }
1.334 if( optind < argc ) {
1.335 - ins_filename = argv[optind++];
1.336 + ins_filename = argv[optind++];
1.337 }
1.338 if( optind < argc ) {
1.339 - act_filename = argv[optind++];
1.340 + act_filename = argv[optind++];
1.341 }
1.342
1.343 if( optind < argc || ins_filename == NULL || act_filename == NULL ) {
1.344 - usage();
1.345 - exit(1);
1.346 + usage();
1.347 + exit(1);
1.348 }
1.349 -
1.350 +
1.351 if( out_filename == NULL ) {
1.352 - if( gen_mode == GEN_TEMPLATE ) {
1.353 - out_filename = act_filename;
1.354 - } else {
1.355 - char tmp[strlen(act_filename)+1];
1.356 - strcpy( tmp, act_filename);
1.357 - char *c = strrchr( tmp, '.' );
1.358 - if( c != NULL ) {
1.359 - *c = '\0';
1.360 - }
1.361 - out_filename = g_strconcat( tmp, DEFAULT_OUT_EXT, NULL );
1.362 - }
1.363 + if( gen_mode == GEN_TEMPLATE ) {
1.364 + out_filename = act_filename;
1.365 + } else {
1.366 + char tmp[strlen(act_filename)+1];
1.367 + strcpy( tmp, act_filename);
1.368 + char *c = strrchr( tmp, '.' );
1.369 + if( c != NULL ) {
1.370 + *c = '\0';
1.371 + }
1.372 + out_filename = g_strconcat( tmp, DEFAULT_OUT_EXT, NULL );
1.373 + }
1.374 }
1.375
1.376 /* Open the files */
1.377 ins_file = fopen( ins_filename, "ro" );
1.378 if( ins_file == NULL ) {
1.379 fprintf( stderr, "Unable to open '%s' for reading (%s)\n", ins_filename, strerror(errno) );
1.380 - exit(2);
1.381 + exit(2);
1.382 }
1.383
1.384 act_file = fopen( act_filename, "ro" );
1.385 if( act_file == NULL ) {
1.386 fprintf( stderr, "Unable to open '%s' for reading (%s)\n", act_filename, strerror(errno) );
1.387 - exit(3);
1.388 + exit(3);
1.389 }
1.390 -
1.391 +
1.392 /* Parse the input */
1.393 struct ruleset *rules = parse_ruleset_file( ins_file );
1.394 fclose( ins_file );
1.395 if( rules == NULL ) {
1.396 - exit(5);
1.397 + exit(5);
1.398 }
1.399
1.400 struct actionset *actions = parse_action_file( rules, act_file );
1.401 fclose( act_file );
1.402 if( actions == NULL ) {
1.403 - exit(6);
1.404 + exit(6);
1.405 }
1.406
1.407 /* Finally write out the results */
1.408 out_file = fopen( out_filename, "wo" );
1.409 if( out_file == NULL ) {
1.410 fprintf( stderr, "Unable to open '%s' for writing (%s)\n", out_filename, strerror(errno) );
1.411 - exit(4);
1.412 + exit(4);
1.413 }
1.414 -
1.415 +
1.416 switch( gen_mode ) {
1.417 case GEN_SOURCE:
1.418 - if( generate_decoder( rules, actions, out_file ) != 0 ) {
1.419 - exit(7);
1.420 - }
1.421 - break;
1.422 + if( generate_decoder( rules, actions, out_file ) != 0 ) {
1.423 + exit(7);
1.424 + }
1.425 + break;
1.426 case GEN_TEMPLATE:
1.427 - if( generate_template( rules, actions, out_file ) != 0 ) {
1.428 - exit(7);
1.429 - }
1.430 - break;
1.431 + if( generate_template( rules, actions, out_file ) != 0 ) {
1.432 + exit(7);
1.433 + }
1.434 + break;
1.435 }
1.436 fclose( out_file );
1.437 return 0;
.