#!/usr/bin/perl
#
# Parse ioregs.h into a .S file to export the register names
# as actual symbols; this is highly useful for debugging.

use strict;
use integer;

my($infile, $outfile) = @ARGV;

unless (defined($outfile)) {
    die "Usage: $0 infile outfile\n";
}

open(my $in, '<', $infile)
    or die "$0: $infile: $!\n";
open(my $out, '>', $outfile)
    or die "$0: $outfile: $!\n";

my %range = ();
my %sizes = ('B' => 1, 'H' => 2, 'L' => 4);
my %syms;

sub outsym($$$$) {
    my($out, $sym, $dev, $size) = @_;

    print $out ".globl $sym\n";
    print $out "$sym = $dev\n";
    if ($size) {
	print $out ".type $sym, \@object\n";
	print $out ".size $sym, $size\n";
    }
}

print $out "\#include \"iodevs.h\"\n";
print $out "\#include \"iodeva.h\"\n";
print $out "\n";

outsym($out, 'IODEV_BASE', 'IODEV_ADDR_BASE', 0);
outsym($out, 'XDEV_BASE', 'XDEV_ADDR_BASE', 0);

while (my $l = <$in>) {
    $l =~ s/^\s+//;
    $l =~ s/\s+$//;

    if ($l =~ /^\/\*\s*(\w+)\s*\=\s*([0-9]+)\s*(\.\.\.\s*([0-9]+))\s*\*\//) {
	$range{$1} = [$2, $3 ? $4 : $2];
    } elsif ($l =~ /^\/\*\s*(\w+)\s*\=\s*\*\//) {
	undef $range{$1};
    } elsif ($l =~ /^\#\s*define\s+(\w+)(\((\w+)\))?\s+(IODEVR?(\w).*)$/) {
	my $sym = $1;
	my $dev = $4;
	my $size = $sizes{$5};
	
	if ($2) {
	    my $v = $3;
	    my $r = $range{$v};
	    next unless (defined($r));

	    for (my $i = $r->[0]; $i <= $r->[1]; $i++) {
		print $out "\#define $v $i\n";
		outsym($out, $sym.$i, $dev, $size);
		print $out "\#undef $v\n";
		print $out "\n";
	    }
	} else {
	    outsym($out, $sym, $dev, $size);
	    print $out "\n";
	}
    }
}

close($in);
close($out);

		    
	
    
    


