diff options
author | H. Peter Anvin <hpa@zytor.com> | 2013-11-24 11:49:24 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2013-11-24 11:49:24 -0800 |
commit | 8b0e5a34fcbc66e04cec3fc297c20a34e79c4dc0 (patch) | |
tree | 4940684325751b3ca44b0d2f165ed528d6859e8b | |
parent | cd4c89bbb9a59c76671f2fe8bdbe0de34e38ef1d (diff) | |
download | nasm-8b0e5a34fcbc66e04cec3fc297c20a34e79c4dc0.tar.gz nasm-8b0e5a34fcbc66e04cec3fc297c20a34e79c4dc0.tar.bz2 nasm-8b0e5a34fcbc66e04cec3fc297c20a34e79c4dc0.zip |
iflag: remove C99 constructs, don't hardcode the number of words
Avoid using C99 constructs when not necessary. Don't hardcode the
number of words when we can autodiscover them.
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r-- | iflag.h | 4 | ||||
-rw-r--r-- | insns-iflags.pl | 53 |
2 files changed, 27 insertions, 30 deletions
@@ -37,10 +37,6 @@ int ilog2_32(uint32_t v); * * iflag_t is defined to store these flags. */ -typedef struct { - uint32_t field[4]; -} iflag_t; - #include "iflaggen.h" #define IF_GENBIT(bit) (UINT32_C(1) << (bit)) diff --git a/insns-iflags.pl b/insns-iflags.pl index 77eefee..632bba3 100644 --- a/insns-iflags.pl +++ b/insns-iflags.pl @@ -135,6 +135,19 @@ my %insns_flag_bit = ( my %insns_flag_hash = (); my @insns_flag_values = (); +my $iflag_words; + +sub get_flag_words() { + my $max = -1; + + foreach my $key (keys(%insns_flag_bit)) { + if (${$insns_flag_bit{$key}}[0] > $max) { + $max = ${$insns_flag_bit{$key}}[0]; + } + } + + return int($max/32)+1; +} sub insns_flag_index(@) { return undef if $_[0] eq "ignore"; @@ -143,34 +156,16 @@ sub insns_flag_index(@) { my $key = join("", @prekey); if (not defined($insns_flag_hash{$key})) { - my @newkey = ([], [], [], []); - my $str = ""; + my @newkey = (0) x $iflag_words; for my $i (@prekey) { die "No key for $i\n" if not defined($insns_flag_bit{$i}); - if ($insns_flag_bit{$i}[0] < 32) { - push @newkey[0], $insns_flag_bit{$i}[0] - 0; - } elsif ($insns_flag_bit{$i}[0] < 64) { - push @newkey[1], $insns_flag_bit{$i}[0] - 32; - } elsif ($insns_flag_bit{$i}[0] < 96) { - push @newkey[2], $insns_flag_bit{$i}[0] - 64; - } elsif ($insns_flag_bit{$i}[0] < 128) { - push @newkey[3], $insns_flag_bit{$i}[0] - 96; - } else { - die "Key value is too big ", $insns_flag_bit{$i}[0], "\n"; - } - } - - for my $j (0 .. $#newkey) { - my $v = ""; - if (scalar(@{$newkey[$j]})) { - $v = join(" | ", map { map { sprintf("(UINT32_C(1) << %d)", $_) } @$_; } $newkey[$j]); - } else { - $v = "0"; - } - $str .= sprintf(".field[%d] = %s, ", $j, $v); + $newkey[$insns_flag_bit{$i}[0]/32] |= + (1 << ($insns_flag_bit{$i}[0] % 32)); } + my $str = join(',', map { sprintf("UINT32_C(0x%08x)",$_) } @newkey); + push @insns_flag_values, $str; $insns_flag_hash{$key} = $#insns_flag_values; } @@ -193,8 +188,12 @@ sub write_iflaggen_h() { } print N "\n"; - print N sprintf("extern iflag_t insns_flags[%d];\n\n", - $#insns_flag_values + 1); + print N "typedef struct {\n"; + printf N " uint32_t field[%d];\n", $iflag_words; + print N "} iflag_t;\n"; + + print N "\n"; + printf N "extern iflag_t insns_flags[%d];\n\n", $#insns_flag_values + 1; print N "#endif /* NASM_IFLAGGEN_H */\n"; close N; @@ -210,10 +209,12 @@ sub write_iflag_c() { print N "/* Global flags referenced from instruction templates */\n"; print N sprintf("iflag_t insns_flags[%d] = {\n", $#insns_flag_values + 1); foreach my $i (0 .. $#insns_flag_values) { - print N sprintf(" [%8d] = { %s },\n", $i, $insns_flag_values[$i]); + print N sprintf(" /* %4d */ {{ %s }},\n", $i, $insns_flag_values[$i]); } print N "};\n\n"; close N; } +$iflag_words = get_flag_words(); + 1; |