File: generate_iga64_codes

package info (click to toggle)
intel-gpu-tools 2.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 63,360 kB
  • sloc: xml: 781,458; ansic: 360,567; python: 8,336; yacc: 2,781; perl: 1,196; sh: 1,177; lex: 487; asm: 227; lisp: 35; makefile: 30
file content (130 lines) | stat: -rwxr-xr-x 4,472 bytes parent folder | download
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