File: jit-comparify-asm.pl

package info (click to toggle)
moarvm 2020.12%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 18,652 kB
  • sloc: ansic: 268,178; perl: 8,186; python: 1,316; makefile: 768; sh: 287
file content (70 lines) | stat: -rwxr-xr-x 2,116 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/env perl
use strict;
use warnings;
use Getopt::Long;
#use Data::Dumper;
my %OPTIONS = (break_ret => 1);

GetOptions(\%OPTIONS, qw(break_ret! crlf));

my %names;
my %labels;
my @instructions;
my $next_global = 0;
my $riprel = undef;
local $/ = "\r\n" if $OPTIONS{crlf};

while (<>) {
    chomp;

    next unless m/^\s*([A-F0-9]+):\s+([A-F0-9]{2} ?)+\s+(\w+)\s+(.+)$/i;
    my ($addr, $opcode, $arg) = (hex($1), $3, $4);

    # remove lines with value bytes
    next if $opcode =~ m/^[0-9A-F]{2}$/i;
    # remove comments
    $arg =~ s/\s+(#.+)$//;

    # rip-relative labels are defined by their end position, hence
    # they are calculate from the address of the next instruction
    if (defined $riprel) {
        $labels{$addr+$riprel} = 1;
        $riprel = undef;
    }
    if ($opcode =~ m/^j\w+$/ && $arg =~ m/^0x/) {
        my $pos = hex($arg);
        $labels{$pos} = 1;
    } elsif ($arg =~ m/\[rip\+(0x[0-9a-f]+)/i)  {
        $riprel = hex($1);
    } elsif ($opcode eq 'movabs') {
        my ($reg,$val) = split /,/, $arg;
        $names{$val} = sprintf('global_%03d', ++$next_global) unless exists $names{$val};
    }
    push @instructions, [$addr, $opcode, $arg];
}

sub sortn { sort { $a <=> $b } @_ }
# assign labels in code order
@labels{sortn keys %labels} = 1..(scalar keys %labels);

for (my $i = 0; $i < @instructions; $i++) {
    my ($addr, $opcode, $arg) = @{$instructions[$i]};
    if (exists $labels{$addr}) {
        # label_ is 6 char, 3 num, 1 colon, 2 space
        print sprintf("label_%03d:  ", $labels{$addr});
    } else {
        print ' ' x 12;
    }
    if ($opcode eq 'movabs') {
        my ($reg,$val) = split /,/, $arg;
        $arg = sprintf('%s,%s', $reg, $names{$val});
    } elsif ($opcode =~ m/^j\w+$/ && $arg =~ m/^0x/) {

        $arg = sprintf('label_%03d', $labels{hex($arg)});
    } elsif ($arg =~ m/\[rip\+(0x[0-9a-f]+)\]/i) {
        my $pos = hex($1) + $instructions[$i+1]->[0];
        $arg = substr($arg,0,$-[0]) . sprintf('label_%03d # rip', $labels{$pos});
    }
    print "$opcode $arg\n";
    last if $OPTIONS{break_ret} and $opcode eq 'ret';
}