#!/bin/sh
#==- gen_isd_opcode_constants ------------- ISD Opcode Constants Generator --==#
#    Copyright (c) 2023 Graphcore Ltd. All Rights Reserved.
#     Licensed under the Apache License, Version 2.0 (the "License");
#     you may not use this file except in compliance with the License.
#     You may obtain a copy of the License at
#
#        http:#www.apache.org/licenses/LICENSE-2.0
#
#     Unless required by applicable law or agreed to in writing, software
#     distributed under the License is distributed on an "AS IS" BASIS,
#     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#     See the License for the specific language governing permissions and
#     limitations under the License.
# --- LLVM Exceptions to the Apache 2.0 License ----
#
# As an exception, if, as a result of your compiling your source code, portions
# of this Software are embedded into an Object form of such source code, you
# may redistribute such embedded portions in such Object form without complying
# with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
#
# In addition, if you combine or link compiled forms of this Software with
# software that is licensed under the GPLv2 ("Combined Software") and if a
# court of competent jurisdiction determines that the patent provision (Section
# 3), the indemnity provision (Section 9) or other Section of the License
# conflicts with the conditions of the GPLv2, you may retroactively and
# prospectively choose to deem waived or otherwise exclude such Section(s) of
# the License, but only in their entirety and only with respect to the Combined
# Software.
#
#===----------------------------------------------------------------------===#
#
# Usage: gen_isd_opcode_constants <OUTPUT>
#
# Generate into <OUTPUT> LLVM IR containing numeric values for ISD nodes for
# use with intrinsics.
#
#===----------------------------------------------------------------------===#

set -e
set -u

out_file="${1}"

# Run the printer program and redirect the output in a cpp file.
isd_opcode_constants_cpp="$(mktemp isd_opcode_constantXXXXXXXXXX.cpp)"
ColossusISDOpcodeConstantsPrinter > "$isd_opcode_constants_cpp"

if [ ! -s "$isd_opcode_constants_cpp" ]; then
  echo "Source file $isd_opcode_constants_cpp is empty."
  return 1
fi

# Rely on the PATH being set up so that the just built clang++ compiler is used
# below when invoking clang++ to compile that cpp file into an LLVM IR file.
# Using the built clang++ avoids needing clang++ installed in the host. clang++
# is invoked via clang because clang++ is not a target created by
# add_executable and it is not obvious that it will be built before the custom
# command executing this script is run.
tmp_isd_file=$(mktemp raw_isd_opcode_constantsXXXXXXXXXX.ll)
clang -x c++ -std=c++11  -emit-llvm -S \
	"$isd_opcode_constants_cpp" -o "$tmp_isd_file"

cat > "$out_file" <<EOL
; RUN: llc %s -o /dev/null
; CHECK-NOT: error
; This file was generated by running gen_isd_opcode_constants
; The alternative is letting llvm's unit tests depend on a copy of clang
EOL
cat "$tmp_isd_file" | grep -Ev '(target datalayout|!1)' \
  | sed "s@$isd_opcode_constants_cpp@isd_opcode_constants.cpp@" >> "$out_file"
rm "$isd_opcode_constants_cpp"
rm "$tmp_isd_file"

exit
