filename | src/tools/insparse.c |
changeset | 359:c588dce7ebde |
next | 420: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 |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/tools/insparse.c Thu Aug 23 12:33:27 2007 +00001.3 @@ -0,0 +1,224 @@1.4 +#include <stdlib.h>1.5 +#include <stdio.h>1.6 +#include <string.h>1.7 +#include <ctype.h>1.8 +#include "tools/gendec.h"1.9 +1.10 +#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)++; }1.11 +static int yyline;1.12 +1.13 +struct rule *new_rule() {1.14 + struct rule *rule = malloc( sizeof( struct rule ) );1.15 + memset( rule, 0, sizeof( struct rule ) );1.16 + return rule;1.17 +}1.18 +1.19 +struct ruleset *parse_ruleset_file( FILE *f )1.20 +{1.21 + struct ruleset *rules = malloc( sizeof(struct ruleset ) );1.22 + char buf[512];1.23 +1.24 + rules->rule_count = 0;1.25 + yyline = 0;1.26 + while( fgets( buf, sizeof(buf), f ) != NULL ) {1.27 + yyline++;1.28 + if( strncasecmp(buf, "registers", 9) == 0 ) {1.29 + parse_registers_block(buf, sizeof(buf), f);1.30 + } else if( buf[0] != '\0' && buf[0] != '#' && buf[0] != '\n' ) {1.31 + struct rule *rule;1.32 + char *p = buf;1.33 + rule = new_rule();1.34 + if( parse_rule( &p, rule ) != 0 ) {1.35 + free( rule );1.36 + } else {1.37 + rules->rules[rules->rule_count++] = rule;1.38 + }1.39 + }1.40 + }1.41 + return rules;1.42 +}1.43 +1.44 +int parse_registers_block( char *buf, int buflen, FILE *f ) {1.45 + do {1.46 + if( strchr(buf, '}') != NULL ) {1.47 + break;1.48 + }1.49 + } while( fgets( buf, buflen, f ) != NULL );1.50 +}1.51 +1.52 +/**1.53 + * Parse a single complete rule1.54 + * @return 0 on success, non-zero on failure1.55 + */1.56 +int parse_rule( char **str, struct rule *rule )1.57 +{1.58 + if( parse_bitstring( str, rule ) != 0 ) {1.59 + return -1;1.60 + }1.61 +1.62 + /* consume whitespace in between */1.63 + while( isspace(**str) ) (*str)++;1.64 + if( **str == '\0' ) {1.65 + fprintf( stderr, "Unexpected end of file in rule on line %d\n", yyline );1.66 + return -1;1.67 + }1.68 +1.69 + int result = parse_rule_format( str, rule );1.70 + if( result == 0 ) {1.71 + /* Reverse operand bit shifts */1.72 + int j;1.73 + for( j=0; j<rule->operand_count; j++ ) {1.74 + rule->operands[j].bit_shift =1.75 + rule->bit_count - rule->operands[j].bit_shift - rule->operands[j].bit_count;1.76 + }1.77 + if( **str == '!' ) {1.78 + (*str)++;1.79 + result = parse_operand_uses( str, rule );1.80 + }1.81 + }1.82 +1.83 + return 0;1.84 +}1.85 +1.86 +int parse_bitstring( char **str, struct rule *rule )1.87 +{1.88 + while( !isspace(**str) ) {1.89 + int ch = **str;1.90 + (*str)++;1.91 + switch( ch ) {1.92 + case '0':1.93 + rule->bits = rule->bits << 1;1.94 + rule->mask = (rule->mask << 1) | 1;1.95 + rule->bit_count++;1.96 + break;1.97 + case '1':1.98 + rule->bits = (rule->bits << 1) | 1;1.99 + rule->mask = (rule->mask << 1) | 1;1.100 + rule->bit_count++;1.101 + break;1.102 + case '(':1.103 + if( parse_bitoperand( str, rule ) != 0 ) {1.104 + return -1 ;1.105 + }1.106 + break;1.107 + default:1.108 + (*str)--;1.109 + fprintf( stderr, "Unexpected character '%c' in bitstring at line %d\n", ch, yyline );1.110 + return -1;1.111 + }1.112 + }1.113 + return 0;1.114 +}1.115 +1.116 +int parse_bitoperand( char **str, struct rule *rule )1.117 +{1.118 + char *p = rule->operands[rule->operand_count].name;1.119 + char tmp[8];1.120 +1.121 + if( rule->operand_count == MAX_OPERANDS ) {1.122 + fprintf( stderr, "Maximum operands/rule exceeded (%d) at line %d\n", MAX_OPERANDS, yyline );1.123 + return -1;1.124 + }1.125 +1.126 + while( isalnum(**str) || **str == '_' ) {1.127 + *p++ = *(*str)++;1.128 + }1.129 + *p = '\0';1.130 + CONSUME_CHAR(':');1.131 +1.132 + int size = parse_integer( str );1.133 + if( size == -1 ) {1.134 + return -1;1.135 + }1.136 + rule->operands[rule->operand_count].bit_count = size;1.137 + if( **str == 's' || **str == 'S' ) {1.138 + (*str)++;1.139 + rule->operands[rule->operand_count].is_signed = 1;1.140 + } else if( **str == 'u' || **str == 'U' ) {1.141 + (*str)++;1.142 + rule->operands[rule->operand_count].is_signed = 0;1.143 + }1.144 + if( **str == '<' ) {1.145 + (*str)++;1.146 + CONSUME_CHAR('<');1.147 + int lsl = parse_integer(str);1.148 + if( lsl == -1 ) {1.149 + return -1;1.150 + }1.151 + rule->operands[rule->operand_count].left_shift = lsl;1.152 + }1.153 + CONSUME_CHAR(')');1.154 +1.155 + rule->operands[rule->operand_count].bit_shift = rule->bit_count;1.156 + rule->bit_count += size;1.157 + rule->bits = rule->bits << size;1.158 + rule->mask = rule->mask << size;1.159 + rule->operand_count++;1.160 + return 0;1.161 +}1.162 +1.163 +int parse_integer( char **str )1.164 +{1.165 + uint32_t val = 0;1.166 + if( !isdigit(**str) ) {1.167 + fprintf(stderr, "Expected digit (0-9) but was '%c' at line %d\n", **str, yyline );1.168 + return -1;1.169 + }1.170 + do {1.171 + val = val * 10 + (**str - '0');1.172 + (*str)++;1.173 + } while( isdigit(**str) );1.174 + return val;1.175 +}1.176 +1.177 +int parse_rule_format( char **str, struct rule *rule )1.178 +{1.179 +1.180 + char tmp[64];1.181 + char *p = tmp;1.182 + while( **str != '\n' && **str != '\0' && **str != '!' ) {1.183 + *p++ = *(*str)++;1.184 + }1.185 + *p = '\0';1.186 + strcpy( rule->format, tmp );1.187 +1.188 + return 0;1.189 +}1.190 +1.191 +int parse_operand_uses( char **str, struct rule *rule )1.192 +{1.193 +1.194 +}1.195 +1.196 +void dump_ruleset( struct ruleset *rules, FILE *f )1.197 +{1.198 + int i, j;1.199 + fprintf( f, "Rulset: %d rules\n", rules->rule_count );1.200 + for( i=0; i<rules->rule_count; i++ ) {1.201 + struct rule *rule = rules->rules[i];1.202 + fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );1.203 + for( j=0; j<rule->operand_count; j++ ) {1.204 + fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,1.205 + rule->operands[j].is_signed ? "signed" : "unsigned",1.206 + rule->operands[j].bit_shift,1.207 + (1<<rule->operands[j].bit_count)-1 );1.208 + }1.209 + fprintf( f, "\n" );1.210 + }1.211 +}1.212 +1.213 +void dump_rulesubset( struct ruleset *rules, int ruleidx[], int rule_count, FILE *f )1.214 +{1.215 + int i,j;1.216 + for( i=0; i<rule_count; i++ ) {1.217 + struct rule *rule = rules->rules[ruleidx[i]];1.218 + fprintf( f, "Match: %08X/%08X %s: ", rule->bits, rule->mask, rule->format );1.219 + for( j=0; j<rule->operand_count; j++ ) {1.220 + fprintf( f, "%s = (%s)(ir>>%d)&0x%X ", rule->operands[j].name,1.221 + rule->operands[j].is_signed ? "signed" : "unsigned",1.222 + rule->operands[j].bit_shift,1.223 + (1<<rule->operands[j].bit_count)-1 );1.224 + }1.225 + fprintf( f, "\n" );1.226 + }1.227 +}
.