#!/usr/sbin/perl

$curfunc = "";		# name of current function
$lastll = "";		# last load linked

# branch instructions
@branchunc = qw(
    b
);
@branchu{@branchunc} = (1) * @branchunc;

# branch 2 reg
@branch2 = qw(
    beq
    bne
    beql
    bnel
);
@branchc{@branch2} = (1) * @branch2;

# branch 1 reg
@branch1 = qw(
    bgez
    bgtz
    blez
    bltz
    bltzal
    bgezal
    bgtzal
    blezal
    bgezl
    bgtzl
    blezl
    bltzl
    bltzall
    bgezall
    bgtzall
    blezall
);
@branchcz{@branch1} = (1) x @branch1;

# load linked loop workaround
@loadl = qw(
    ll
    lld
);
@loadll{@loadl} = (1) x @loadl;

while (<>) {
    if (/^[_a-zA-Z][_a-zA-Z0-9]*:$/) {
	($curfunc = $_) =~ s/:\n//;
	next;
    }
    if ($curfunc eq "") {
	# Still reading initial disassembly header
	next;
    }
    if (($instr = $_) !~ s/^.* ([_a-z0-9]*)\t.*\n/$1/) {
	if ($instr !~ s/^.* ([_a-z0-9]*)\n/$1/) {
	    print STDERR "$ARGV, $., $curfunc: warning: unknown line format:\n";
	    print STDERR ">> $_";
	    next;
	}
    }
    $btarg = "";
    if (exists $branchu{$instr}) {
	($btarg = $_) =~ s/^.* [_a-z0-9]*\t*(.*)\n/$1/;
    } 
    if (exists $branchc{$instr}) {
	($btarg = $_) =~ s/^.* [_a-z0-9]*\t.*,.*,(.*)\n/$1/;
    }
    if (exists $branchcz{$instr}) {
	($btarg = $_) =~ s/^.* [_a-z0-9]*\t.*,(.*)\n/$1/;
    }
    if (exists $loadll{$instr}) {
	($lastll = $_) =~ s/^.*(0x[0-9a-f]*):.*\n/$1/;
	next;
    } 
    if ($btarg eq "") {
        next;
    }
    if ($btarg eq $lastll) {
	print STDERR "found sc/ll loop at $lastll\n";
	$lastll = "";
	next;
    }
    $lastll = "";
    print "$btarg\n";
} continue {
    if (eof) {
	# reset line number counter $.
	close ARGV;
    }
}
