#!/usr/bin/perl
#############################################################################
#    (c)2010 Broadcom Corporation
#
# This program is the proprietary software of Broadcom Corporation and/or its licensors,
# and may only be used, duplicated, modified or distributed pursuant to the terms and
# conditions of a separate, written license agreement executed between you and Broadcom
# (an "Authorized License").  Except as set forth in an Authorized License, Broadcom grants
# no license (express or implied), right to use, or waiver of any kind with respect to the
# Software, and Broadcom expressly reserves all rights in and to the Software and all
# intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
# HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
# NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
#
# Except as expressly set forth in the Authorized License,
#
# 1.     This program, including its structure, sequence and organization, constitutes the valuable trade
# secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
# and to use this information only in connection with your use of Broadcom integrated circuit products.
#
# 2.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
# AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
# WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
# THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
# OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
# LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
# OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
# USE OR PERFORMANCE OF THE SOFTWARE.
#
# 3.     TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
# LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
# EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
# USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
# ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
# LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
# ANY LIMITED REMEDY.
#
# $brcm_Workfile: jumptable.pl $
# $brcm_Revision: 2 $
# $brcm_Date: 9/21/10 2:47p $
#
# Module Description:
# This perl script generates a file that contains all of the asm stubs for either
# the forward or the reverse APIs. That is to say it is used twice, one for each.
#
# Revision History:
#
# $brcm_Log: /nexus/build/tools/jumptable/jumptable.pl $
# 
# 2   9/21/10 2:47p erickson
# SW7420-943: replace (void*) with jumptable entry type to clean up
#  warning
#
# 1   8/12/10 1:49p ttrammel
# SW7420-943: Merge NFE to main branch.
#
# NFE/3   5/21/10 1:19p ttrammel
# SW7405-4364: Only remove symbol strings from firmware blob.
#
# NFE/2   5/18/10 3:30p ttrammel
# SW7405-4315: Initial NFE check-in. Remove FEXPORT of syms.
#
#############################################################################
use strict;

my $i;
my $index;
my @funcs;
my $varname;

$index = 0;

if ( $#ARGV < 2 )
{
   die "usage: jumptable.pl <jumptable source filename> <stub library filename> <input text file1> ... <input text file n>";
}

# First arg is the  unique variable tag so we can build multiple tables
$varname = @ARGV[0];

# Second arg is the name of the static library.  Remaining args are input text files for global function names.
for ($i=3;$i<=$#ARGV;$i++)
{
   open INFILE, "< @ARGV[$i]" or die $!;

   while (<INFILE>)
   {
      my $line = $_;
      # Strip comments
      $line =~ s/#.*?\n//g;
      # Strip newline
      chomp $line;
      if ( length $line > 0 )
      {
         $funcs[$index] = $line;
         $index++;
      }
   }

   close INFILE
}

# Write jumptable itself to a file
open OUTFILE, "> @ARGV[1]" or die $!;
# Write banner
print OUTFILE "/****************************************************\n";
print OUTFILE "* This file is automatically generated.  Do not edit.\n";
print OUTFILE "****************************************************/\n";
print OUTFILE "\n";

# First write prototypes to avoid warnings
$i = 0;
while ($i < $index)
{
   print OUTFILE "extern int $funcs[$i](void);\n";
   $i++;
}

my $table_entry_type = "B_$varname\_Jumptable_Entry";
# Write table itself
print OUTFILE "\ntypedef int (*$table_entry_type)(void); \n";
print OUTFILE "\n$table_entry_type B_$varname\_Jumptable[] = \n{\n";
$i = 0;
while ($i < $index)
{
   print OUTFILE "$funcs[$i],\n";
   $i++;
}
print OUTFILE "($table_entry_type)-1\n};\n";
print OUTFILE "\n$table_entry_type *p$varname\_Jumptable = B_$varname\_Jumptable;\n";

close OUTFILE;

# The kernel will place the jumptable address in $gp by convention.  Write stub .s file to call the function from the table.
$i = 0;
open OUTFILE, "> @ARGV[2]" or die $!;
# Write banner
print OUTFILE "/****************************************************\n";
print OUTFILE "* This file is automatically generated.  Do not edit.\n";
print OUTFILE "****************************************************/\n";
print OUTFILE "\n";

# For the reverse case, put our table pointer in this file as well
if ($varname eq "Reverse") {
print OUTFILE ".data\n.align 4\n.globl p$varname\_Jumptable\np$varname\_Jumptable: .space 4\n";
}

print OUTFILE ".text\n";

while ($i < $index)
{
   my $offset = $i*4;
   print OUTFILE ".globl $funcs[$i]\n.set noreorder\n$funcs[$i]:\nlw \$9,p$varname\_Jumptable\nlw \$8,$offset(\$9)\n";
   print OUTFILE "j \$8\nnop\n.set reorder\n\n";

   $i++;
}
close OUTFILE;

