#!/bin/bash
#
#  make_generated_offload_arch_h.sh - Create the fle generated_offload_arch.h
#
# Written by Greg Rodgers Gregory.Rodgers@amd.com
# Copyright (c) 2021 ADVANCED MICRO DEVICES, INC.
#
# AMD is granting you permission to use this software and documentation (if any) (collectively, the
# Materials) pursuant to the terms and conditions of the Software License Agreement included with the
# Materials.  If you do not have a copy of the Software License Agreement, contact your AMD
# representative for a copy.
#
# You agree that you will not reverse engineer or decompile the Materials, in whole or in part, except for
# example code which is provided in source code form and as allowed by applicable law.
#
# WARRANTY DISCLAIMER: THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
# KIND.  AMD DISCLAIMS ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING BUT NOT
# LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
# PURPOSE, TITLE, NON-INFRINGEMENT, THAT THE SOFTWARE WILL RUN UNINTERRUPTED OR ERROR-
# FREE OR WARRANTIES ARISING FROM CUSTOM OF TRADE OR COURSE OF USAGE.  THE ENTIRE RISK
# ASSOCIATED WITH THE USE OF THE SOFTWARE IS ASSUMED BY YOU.  Some jurisdictions do not
# allow the exclusion of implied warranties, so the above exclusion may not apply to You.
#
# LIMITATION OF LIABILITY AND INDEMNIFICATION:  AMD AND ITS LICENSORS WILL NOT,
# UNDER ANY CIRCUMSTANCES BE LIABLE TO YOU FOR ANY PUNITIVE, DIRECT, INCIDENTAL,
# INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING FROM USE OF THE SOFTWARE OR THIS
# AGREEMENT EVEN IF AMD AND ITS LICENSORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGES.  In no event shall AMD's total liability to You for all damages, losses, and
# causes of action (whether in contract, tort (including negligence) or otherwise)
# exceed the amount of $100 USD.  You agree to defend, indemnify and hold harmless
# AMD and its licensors, and any of their directors, officers, employees, affiliates or
# agents from and against any and all loss, damage, liability and other expenses
# (including reasonable attorneys' fees), resulting from Your use of the Software or
# violation of the terms and conditions of this Agreement.
#
# U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with "RESTRICTED RIGHTS."
# Use, duplication, or disclosure by the Government is subject to the restrictions as set
# forth in FAR 52.227-14 and DFAR252.227-7013, et seq., or its successor.  Use of the
# Materials by the Government constitutes acknowledgement of AMD's proprietary rights in them.
#
# EXPORT RESTRICTIONS: The Materials may be subject to export restrictions as stated in the
# Software License Agreement.
#

INPUTDIR=$1
if [ -z $INPUTDIR ] ; then
  INPUTDIR=$PWD
fi

# These are the input files
AOT_PCIID2CODENAME="$INPUTDIR/amdgpu/pciid2codename.txt $INPUTDIR/nvidia/pciid2codename.txt"
AOT_CODENAME2OFFLOADARCH="$INPUTDIR/amdgpu/codename2offloadarch.txt $INPUTDIR/nvidia/codename2offloadarch.txt"

# This is the output file which is always written to current dir
AOT_DOTH_FILE="$PWD/generated_offload_arch.h"

function get_offloadarch_id_from_codename
{
   _codename=$1
   _entry=`grep -m1 "^$_codename" $AOT_CODENAME2OFFLOADARCH`
   if [ $? == 0 ] ; then
      _offloadarchid=`echo $_entry | awk '{print $2}'`
   else
      _offloadarchid="$_codename"
   fi
   echo $_offloadarchid
}

function write_AOT_OFFLOADARCH()
{
  echo "typedef enum {" >> $AOT_DOTH_FILE
  cat $AOT_CODENAME2OFFLOADARCH | cut -d" " -f2 | sort -u > $aot_tmpfile
  while read -r line ; do
    echo "  AOT_${line^^}," >> $AOT_DOTH_FILE
  done < $aot_tmpfile
  echo "} AOT_OFFLOADARCH;" >> $AOT_DOTH_FILE
}

function write_AOT_CODENAME()
{
  echo "typedef enum {" >> $AOT_DOTH_FILE
  cat $AOT_CODENAME2OFFLOADARCH | while read -r line ; do
    codename=`echo $line | cut -d" " -f1`
    echo "  AOT_CN_${codename^^}," >> $AOT_DOTH_FILE
  done
  echo "} AOT_CODENAME;" >> $AOT_DOTH_FILE
}
function write_AOT_CODENAMEID_TO_STRING()
{
  echo "extern const AOT_CODENAME_ID_TO_STRING AOT_CODENAMES[] =  {" >>$AOT_DOTH_FILE
  cat $AOT_CODENAME2OFFLOADARCH | while read -r line ; do
    codename=`echo $line | cut -d" " -f1`
    echo "  {AOT_CN_${codename^^}, \"${codename}\"}," >> $AOT_DOTH_FILE
  done
  echo "};" >> $AOT_DOTH_FILE
}
function write_AOT_OFFLOADARCH_TO_STRING()
{
  echo "extern const AOT_OFFLOADARCH_TO_STRING AOT_OFFLOADARCHS[] =  {" >>$AOT_DOTH_FILE
  cat $AOT_CODENAME2OFFLOADARCH | cut -d" " -f2 | sort -u > $aot_tmpfile
  while read -r line ; do
    echo "  {AOT_${line^^}, \"${line}\"}," >> $AOT_DOTH_FILE
  done < $aot_tmpfile
  echo "};" >> $AOT_DOTH_FILE
}

function write_AOT_PROLOG()
{
/bin/cat 2>&1 <<"EOF" > $aot_tmpfile
//  This file is generated by make_generated_offload_arch_h.sh
//  It is only included by OffloadArch.cpp
#include <stddef.h>
#include <stdint.h>
EOF
cat $aot_tmpfile >> $AOT_DOTH_FILE
}

function write_AOT_STRUCTS()
{
/bin/cat 2>&1 <<"EOF" > $aot_tmpfile

struct AOT_CODENAME_ID_TO_STRING{
  AOT_CODENAME codename_id;
  const char* codename;
};

struct AOT_OFFLOADARCH_TO_STRING{
  AOT_OFFLOADARCH offloadarch_id;
  const char* offloadarch;
};

struct AOT_TABLE_ENTRY{
    uint16_t vendorid;
    uint16_t devid;
    AOT_CODENAME codename_id;
    AOT_OFFLOADARCH offloadarch_id;
};
EOF
cat $aot_tmpfile >> $AOT_DOTH_FILE
}

function write_AOT_TABLE()
{
  echo "extern const AOT_TABLE_ENTRY AOT_TABLE[] = {" >>$AOT_DOTH_FILE
  cat $AOT_PCIID2CODENAME | sort -u -t" " -k1 > $aot_tmpfile
  while read -r line ; do
    codename=`echo $line | cut -d" " -f4`
    # only proceed if we know about this codename
    grep -q "^$codename " $AOT_CODENAME2OFFLOADARCH
    if [ $? == 0 ] ; then 
       vid=`echo $line | cut -d":" -f1`
       devid=`echo $line | cut -d" " -f1 | cut -d":" -f2`
       offloadarchid=$(get_offloadarch_id_from_codename $codename)
       echo "{ 0x${vid}, 0x${devid}, AOT_CN_${codename^^}, AOT_${offloadarchid^^} }," >>$AOT_DOTH_FILE
    fi
  done < $aot_tmpfile
  echo "};" >> $AOT_DOTH_FILE
}

#  ===========  Main code starts here ======================

# we dont want to append to existing file
[ -f $AOT_DOTH_FILE ] && rm $AOT_DOTH_FILE
touch $AOT_DOTH_FILE

aot_tmpfile="/tmp/zz$$"

write_AOT_PROLOG
write_AOT_OFFLOADARCH
write_AOT_CODENAME
write_AOT_STRUCTS
write_AOT_CODENAMEID_TO_STRING
write_AOT_OFFLOADARCH_TO_STRING
write_AOT_TABLE

rm $aot_tmpfile

exit 0
