Search
lxdream.org :: lxdream/src/tools/insparse.c :: diff
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
file annotate diff log raw
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/src/tools/insparse.c Thu Aug 23 12:33:27 2007 +0000
1.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 rule
1.54 + * @return 0 on success, non-zero on failure
1.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 +}
.