Merge pull request #218 from saper/build-fixes
[envytools.git] / bftool
blob7b1225e0be6471240c60d52ba9af2a31084d4737
1 #!/usr/bin/perl -sw
2 #RE tool, decodes hex into bitfield descriptions {pos,len}
3 # supports disjoint bitfields
4 # supports mixed 64bit and 32bit (in envydis's endianness) hex words
5 # modes: and, or, xor (mask, diff)
6 #Examples:
7 # find a diff between two OPs:
8 # ./bftool -op=xor 8540dc00001c0002 8540dc00001c3c02
9 # or ./bftool -op=xor 8540dc00001c0002 001c3c02 8540dc00
10 # or ./bftool -op=xor 001c0002 8540dc00 001c3c02 8540dc00
11 # > x: U8{0x8540dc00001c0002} U4{0x001c0002,0x8540dc00}
12 # y: U8{0x8540dc00001c3c02} U4{0x001c3c02,0x8540dc00}
13 # z: U8{0x0000000000003c00} U4{0x00003c00,0x00000000}
14 # {pos,len} = {10,4} = {0xa,4}
15 # find a match against a mask:
16 # ./bftool -op=and 3fc0000000000000 8540dc00001c0002
17 # or ./bftool -op=and 3fc0000000000000 001c0002 8540dc00
18 # ...
19 # U8{0x0540000000000000} U4{0x00000000,0x05400000}
20 # 54,1
21 # 56,1
22 # 58,1
23 use Data::Dumper;
24 no warnings "portable";
25 my $op = $op || "nop";
26 sub readhex{
27 my $A = shift;
28 my $x = shift(@$A);
29 return undef if not defined($x);
30 return hex($x) if(length($x)>8 or scalar(@$A)==0 or length($A->[0])>8);
31 my $y = shift(@$A);
32 return hex($x)|hex($y) << 32;
34 my $x = readhex(\@ARGV) || undef;
35 my $y = readhex(\@ARGV) || undef;
36 my $z = 0;
37 if($op eq "nop"){
38 $z = $x;
40 elsif($op eq "and"){
41 $z = $x & $y;
43 elsif($op eq "xor"){
44 $z = $x ^ $y;
46 elsif($op eq "or"){
47 $z = $x | $y;
49 print sprintf("x: U8{0x%016x} U4{0x%08x,0x%08x}\n",$x,$x&0xFFFFFFFF,($x>>32)&0xFFFFFFFF);
50 print sprintf("y: U8{0x%016x} U4{0x%08x,0x%08x}\n",$y,$y&0xFFFFFFFF,($y>>32)&0xFFFFFFFF);
51 print sprintf("z: U8{0x%016x} U4{0x%08x,0x%08x}\n",$z,$z&0xFFFFFFFF,($z>>32)&0xFFFFFFFF);
52 my $pos=0;
53 while($z!=0){
54 while(($z&0x1) eq 0){
55 $pos++;
56 $z = $z >> 1;
58 my $len=0;
59 while(($z&0x1) eq 1){
60 $len++;
61 $z = $z >> 1;
63 print sprintf("{pos,len} = {%d,%d} = {0x%x,%d}\n",$pos,$len,$pos,$len);
64 $pos+=$len;