Search
lxdream.org :: lxdream/src/tools/insparse.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/tools/insparse.c
changeset 359:c588dce7ebde
next420:e6f43dec3cf0
author nkeynes
date Thu Aug 23 12:33:27 2007 +0000 (14 years ago)
permissions -rw-r--r--
last change Commit decoder generator
Translator work in progress
Fix mac.l, mac.w in emu core
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 }
.