#!/bin/bash
# init.sh                                              2022-04-29 Agner Fog

# Initialization of files before running test scripts
# (c) Copyright 2014-2022 by Agner Fog. GNU General Public License www.gnu.org/licenses


# make all scripts executable
chmod u+x *.sh*

# create results directories if they don't exist
if [ ! -d results ] ; then 
   echo "Creating directory results"
   mkdir results
fi
if [ ! -d results1 ] ; then 
   echo "Creating directory results1"
   mkdir results1
fi
if [ ! -d results2 ] ; then
   echo "Creating directory results2"
   mkdir results2
fi

# Compile cpugetinfo.cpp if modified
if [ cpugetinfo.cpp -nt cpugetinfo ] ; then
   echo "Compiling cpugetinfo.cpp"
   g++ -O2 -m64 -fno-pie -no-pie -ocpugetinfo cpugetinfo.cpp
fi

# Create cpuinfo.txt with instruction sets
# if [ cpugetinfo -nt cpuinfo.txt ] ; then
echo "Creating file cpuinfo.txt"
./cpugetinfo instructionsets > cpuinfo.txt
# fi

# get diagnostics from test program to get information about PMC scheme
g++ -O2 -c -m64 -oa64.o PMCTestA.cpp
nasm -f elf64 -o b64.o -DWINDOWS=0 PMCTestB64.nasm
g++ a64.o b64.o -ox -lpthread
./x diagnostics >> cpuinfo.txt 

# Check if 32 bit mode included
if [ -n "$1" -a 1$1 -eq 164 ] ; then
   echo "64 bit only"
   echo " no32bit " >> cpuinfo.txt
   use32=0
else
   echo "32 and 64 bits"
   use32=1
fi


# Detect CPU specific variables, etc.
. vars.sh


# Compile A file if modified

if [ $use32 -ne 0 ] ; then
if [ PMCTestA.cpp -nt a32.o ] ; then
   echo "Compiling PMCTestA.cpp, 32 bit"
   g++ -O2 -c -m32 -fno-pie -no-pie -oa32.o PMCTestA.cpp
fi
fi

if [ PMCTestA.cpp -nt a64.o ] ; then
   echo "Compiling PMCTestA.cpp, 64 bit"
   g++ -O2 -c -m64 -fno-pie -no-pie -oa64.o PMCTestA.cpp
fi


# Check if nasm version is high enough
nasmversion=`nasm -v | sed 's/[^0-9]*\([0-9.]*\).*/\1/' | sed 's/\.//g'`
if [ `./cpugetinfo -avx2` -gt 0 -a $nasmversion -lt 21000 ] ; then
  echo 'Warning: nasm version too low for AVX2 instruction set'
elif [ `./cpugetinfo -avx` -gt 0 -a $nasmversion -lt 20400 ] ; then
  echo 'Warning: nasm version too low for AVX instruction set'
fi

# Make countertypes.inc file with CPU specific variables etc.
# This file will be included in script templates
echo "Creating file countertypes.inc"
echo -e "; This file is autogenerated. Edit vars.sh and init.sh instead"  > countertypes.inc
echo -e "\n; Operating system:"  >> countertypes.inc
echo -e "%define `./cpugetinfo system` 1"  >> countertypes.inc
echo -e "\n; CPU:"  >> countertypes.inc
echo -e "%define CPUbrand `./cpugetinfo vendor`"  >> countertypes.inc
echo -e "%define ifamily `./cpugetinfo family`"  >> countertypes.inc
echo -e "%define imodel `./cpugetinfo model`"  >> countertypes.inc
echo -e "\n; Define whether AVX and YMM registers used"  >> countertypes.inc
if   [ `grep -c -i "avx" cpuinfo.txt ` -ne 0 ] ; then
echo -e "%define  USEAVX   1"  >> countertypes.inc
else
echo -e "%define  USEAVX   0"  >> countertypes.inc
fi
echo -e "\n; PMC counters:"  >> countertypes.inc
echo -e "%ifndef counters"  >> countertypes.inc
echo -e "%define counters $PMCs"  >> countertypes.inc
echo -e "%endif\n"  >> countertypes.inc


# Make info.txt file with all information
echo "Creating file results1/info.txt"
echo -e "Info about this computer\n"  > results1/info.txt

# System version
if [ -e /proc/version ] ; then
echo -e "\n\n/proc/version:\n"  >> results1/info.txt
cat /proc/version >> results1/info.txt
echo -e "\n\nkernel version:\n"  >> results1/info.txt
uname -a  >> results1/info.txt
fi

# compiler and assembler versions
echo -e "\n\ng++ version:" >> results1/info.txt
g++ --version >> results1/info.txt

if [ $ass = nasm ] ; then
echo -e "\n\nnasm version:" >> results1/info.txt
nasm -v >> results1/info.txt
elif [ $ass = yasm ] ; then
echo -e "\n\nyasm version:" >> results1/info.txt
yasm --version >> results1/info.txt
else 
echo -e "\n\nAssembler: $ass \nversion:" >> results1/info.txt
$ass -version >> results1/info.txt
$ass --version >> results1/info.txt
fi

# Get info from cpugetinfo program
echo -e "\n\nFrom cpugetinfo:"  >> results1/info.txt
./cpugetinfo all >> results1/info.txt

# Get info from /proc/cpuinfo (Linux only):
if [ -e /proc/cpuinfo ] ; then
echo -e "\n\nFrom /proc/cpuinfo:\n"  >> results1/info.txt
cat /proc/cpuinfo >> results1/info.txt
fi

# Get info from cpuz program (Windows only):
if [ -e cpuz.exe ] ; then
echo -e "\n\nFrom cpuz.exe:\n"  >> results1/info.txt
cpuz.exe -txt=cpuinfo1
cat cpuinfo1.txt >> results1/info.txt
fi

# check if we can compile and if driver is installed
nasm -f elf64 -o b64.o -Dinstruct=nop -Dnumop=0 -Dtmode=T -Plt.inc TemplateB64.nasm
if [ $? -ne 0 ] ; then 
  echo -e "\nError: Assembly failed"
  exit
fi
g++ -m64 -fno-pie -no-pie a64.o b64.o -lpthread -ox
if [ $? -ne 0 ] ; then 
  echo -e "\nError: compiling failed"
  exit
fi
# run compiled test program
./x > /dev/null
resultcode=$?
if [ $resultcode -ne 0 ] ; then
  if [ $resultcode -eq 1 ] ; then
  echo -e "\nError: MSR driver not installed"
  elif [ $resultcode -eq 6 -a `./cpugetinfo system` = WINDOWS ] ; then
  echo -e "\nError: Must run as administrator"
  else
  echo -e "\nError: Cannot run test program. Error code $resultcode"
  fi
  exit
fi
