1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#!/bin/bash
# SPDX-License-Identifier: MIT
# Copyright © 2024 Intel Corporation
# Author: Andrzej Hajda <andrzej.hajda@intel.com>
# List of supported platforms, in format gen100:platform, where gen100 equals
# to minimal GPU generation supported by platform multiplied by 100 and platform
# is one of platforms supported by -p switch of iga64.
# Must be in decreasing order, the last one must have gen100 equal 0.
GEN_VERSIONS="2000:2 1270:12p71 1260:12p72 1250:12p5 0:12p1"
# Magic values to encode asm template args, must be the the same as in gpgpu_shader.c.
IGA64_ARG0=0xc0ded000
IGA64_ARG_MASK=0xffffff00
warn() {
echo -e "$1" >/dev/stderr
}
die() {
warn "DIE: $1"
exit 1
}
: ${IGT_SRCDIR:=..}
# parse args
while getopts ':i:o:' opt; do
case $opt in
i) INPUT=$OPTARG;;
o) OUTPUT=$OPTARG;;
?) die "Usage: $0 -i pre-generated-iga64-file -o generated-iga64-file obj-with-iga64-assembly [...]"
esac
done
OBJ=${@:OPTIND}
# read all assemblies into ASMS array
ASMS=()
while read -d $'\0' asm; do
test -z "$asm" && continue
ASMS+=( "$asm" )
done < <(objcopy --dump-section .iga64_assembly=/dev/stdout $OBJ /dev/null)
# check if we need to recompile - checksum difference and compiler present
MD5_ASMS="$(md5sum <<< "$(< $IGT_SRCDIR/lib/iga64_macros.h) ${ASMS[@]}" | cut -b1-32)"
MD5_PRE="$(grep -Po '(?<=^#define MD5_SUM_IGA64_ASMS )\S{32,32}' $INPUT 2>/dev/null)"
if [ "$MD5_ASMS" = "$MD5_PRE" ]; then
echo "iga64 assemblies not changed, reusing pre-compiled file $INPUT."
cp -p $INPUT $OUTPUT
exit 0
fi
type iga64 >/dev/null || {
warn "WARNING: iga64 assemblies changed, but iga64 compiler not present, CHANGES will have no effect. Install iga64 (libigc-tools package) to re-compile code."
cp -p $INPUT $OUTPUT
exit 0
}
# generate code file
WD=$OUTPUT.d
mkdir -p $WD
# check if all required platforms are supported
touch $WD/empty
for gen in $GEN_VERSIONS; do
gen_name="${gen#*:}"
iga64 -p=$gen_name -d $WD/empty 2>/dev/null || {
warn "WARNING: iga64 assemblies changed, but iga64 compiler does not support platform '$gen_name', CHANGES will have no effect. Update iga64 (libigc-tools package) to re-compile code."
cp -p $INPUT $OUTPUT
exit 0
}
done
# returns count of numbers in strings of format "0x1234, 0x23434, ..."
dword_count() {
n=${1//[^x]}
echo ${#n}
}
echo "Generating new $OUTPUT"
cat <<-EOF >$OUTPUT
// SPDX-License-Identifier: MIT
// Generated using $(iga64 |& head -1)
#include "gpgpu_shader.h"
#define MD5_SUM_IGA64_ASMS $MD5_ASMS
EOF
# Compiles assembly to binary representation sent to stdout.
compile_iga64() {
cmd="cpp -P - -o $WD/$asm_name.$gen_name.asm"
cmd+=" -DGEN_VER=$gen_ver -D'ARG(n)=$IGA64_ARG0 + n' -imacros $IGT_SRCDIR/lib/iga64_macros.h"
eval "$cmd" <<<"$asm_body" || die "cpp error for $asm_name.$gen_name\ncmd: $cmd"
cmd="iga64 -Xauto-deps -Wall -p=$gen_name"
cmd+=" $WD/$asm_name.$gen_name.asm"
[ -n "$SHOW_CMD" ] && warn "$cmd"
eval "$cmd" || die "iga64 error for $asm_name.$gen_name\ncmd: $cmd"
}
for asm in "${ASMS[@]}"; do
asm_name="${asm%%:*}"
asm_code="${asm_name/assembly/code}"
asm_body="${asm#*:}"
cur_code="NONE"
cur_ver=""
echo -e "\nstruct iga64_template const $asm_code[] = {" >>$OUTPUT
for gen in $GEN_VERSIONS; do
gen_ver="${gen%%:*}"
gen_name="${gen#*:}"
# Verify generated code will not contain IGA64_ARGs.
for d in $(IGA64_ARG0=0 compile_iga64 | hexdump -v -e '1/4 "0x%08x\n"'); do
(( (d & IGA64_ARG_MASK) == IGA64_ARG0 )) || continue
die "Assembly for $asm_name.$gen_name contains instruction which compiles to $d, conflicts with IGA64_ARG0/mask $IGA64_ARG0/$IGA64_ARG_MASK\ncmd: $cmd"
done
SHOW_CMD=1 compile_iga64 > "$WD/$asm_name.$gen_name.bin" || die "Cannot write to $WD/$asm_name.$gen_name.bin"
code="$(hexdump -v -e '"\t\t" 4/4 "0x%08x, " "\n"' $WD/$asm_name.$gen_name.bin)"
[ "$cur_code" = "NONE" ] && cur_code="$code"
[ "$cur_code" != "$code" ] && {
echo -e "\t{ .gen_ver = $cur_ver, .size = $(dword_count "$cur_code"), .code = (const uint32_t []) {\n$cur_code\n\t}}," >>$OUTPUT
cur_code="$code"
}
cur_ver=$gen_ver
done
echo -e "\t{ .gen_ver = $cur_ver, .size = $(dword_count "$cur_code"), .code = (const uint32_t []) {\n$cur_code\n\t}}\n};" >>$OUTPUT
done
cp -vp $OUTPUT $INPUT
|