aboutsummaryrefslogtreecommitdiff
path: root/risugen
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2011-03-08 17:31:12 +0000
committerPeter Maydell <peter.maydell@linaro.org>2011-03-08 17:33:26 +0000
commit65f3162cf741db6516cd285777b22bd19a28cb1c (patch)
treedf87646a1e4fdcc791af54baab7bac13b416d33b /risugen
parent5e061a7acc42f5b4928d323354dd4a2a556f73bc (diff)
Allow named blocks in risu config files; restrict blocks to end of line
Force blocks in risu config files to be at the ends of lines. Allow them to be named (with an unnamed block being a constraints block for backwards compatibility). At the moment the only recognised block is "constraints".
Diffstat (limited to 'risugen')
-rwxr-xr-xrisugen44
1 files changed, 36 insertions, 8 deletions
diff --git a/risugen b/risugen
index 5c212eb..29099f6 100755
--- a/risugen
+++ b/risugen
@@ -38,6 +38,9 @@ my $bytecount;
#
# We store these in the insn_details hash.
+# Valid block names (keys in blocks hash)
+my %valid_blockname = ( constraints => 1 );
+
sub open_bin
{
my ($fname) = @_;
@@ -267,7 +270,7 @@ sub dump_insn_details($$)
my $fixedbitmask = $rec->{fixedbitmask};
my $constraint = $rec->{blocks}{"constraints"};
print sprintf(" insnwidth %d fixedbits %08x mask %08x ", $insnwidth, $fixedbits, $fixedbitmask);
- if ($constraint ne "") {
+ if (defined $constraint) {
print "constraint $constraint ";
}
for my $tuple (@{ $rec->{fields} }) {
@@ -307,7 +310,7 @@ sub gen_one_insn($$)
}
}
}
- if ($constraint ne "") {
+ if (defined $constraint) {
# user-specified constraint: evaluate in an environment
# with variables set corresponding to the variable fields.
my $evalstr = "{ ";
@@ -538,14 +541,35 @@ sub parse_config_file($)
my $fixedbitmask = 0;
my $bitpos = 32;
my $insnwidth = 32;
- my $constraint = '';
- foreach my $bit (@bits) {
+ my $seenblock = 0;
+
+ while (@bits) {
+ my $bit = shift @bits;
my $bitlen;
my $bitval;
my $var;
- if ($bit =~ /^{/) {
- # Constraint block
- $constraint = $bit;
+
+ if ($bit =~ /^\!/) {
+ # A named block
+ my $blockname = $bit;
+ $blockname =~ s/^!//;
+ my $block = shift @bits;
+ print "blockname $blockname block $block\n";
+ if (!defined $block || $block !~ /^{/) {
+ print STDERR "$file:$.: expected block following '!$blockname'\n";
+ exit(1);
+ }
+ if (!$valid_blockname{$blockname}) {
+ print STDERR "$file:$.: unknown block name '$blockname'\n";
+ exit(1);
+ }
+ $insnrec->{blocks}{$blockname} = $block;
+ $seenblock++;
+ next;
+ } elsif ($bit =~ /^{/) {
+ # An unnamed block is constraints, for backcompatibility
+ $insnrec->{blocks}{"constraints"} = $bit;
+ $seenblock++;
next;
} elsif ($bit =~ /^[01]*$/) {
# fixed bits
@@ -564,6 +588,11 @@ sub parse_config_file($)
exit(1);
}
+ if ($seenblock) {
+ print STDERR "$file:$.: blocks may not occur in the middle of a pattern\n";
+ exit(1);
+ }
+
my $bitmask = oct("0b". '1' x $bitlen);
$bitpos -= $bitlen;
if ($bitpos < 0) {
@@ -596,7 +625,6 @@ sub parse_config_file($)
$insnrec->{width} = $insnwidth;
$insnrec->{fixedbits} = $fixedbits;
$insnrec->{fixedbitmask} = $fixedbitmask;
- $insnrec->{blocks}{"constraints"} = $constraint;
$insnrec->{fields} = [ @fields ];
$insn_details{$insnname} = $insnrec;
}