filename | src/tools/gendec.c |
changeset | 736:a02d1475ccfd |
prev | 561:533f6b478071 |
next | 824: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 +00001.2 +++ b/src/tools/gendec.c Thu Aug 07 23:32:34 2008 +00001.3 @@ -50,13 +50,13 @@1.4 * Find a mask that can be used to split up the given rules1.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.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.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.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.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.63 @@ -105,24 +105,24 @@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.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.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.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.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.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 complex1.186 - * data structures. For now though, this keeps it simple1.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 complex1.233 + * data structures. For now though, this keeps it simple1.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.274 @@ -229,15 +229,15 @@1.275 int i;1.277 for( i=0; i<rules->rule_count; i++ ) {1.278 - ruleidx[i] = i;1.279 + ruleidx[i] = i;1.280 }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.287 fputs( actions->posttext, f );1.288 -1.289 +1.290 return 0;1.291 }1.293 @@ -248,12 +248,12 @@1.294 fputs( "%%\n", f );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.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.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.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.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.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.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;
.