Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/freedreno/computerator/examples/test-opcodes.sh
4570 views
1
#!/bin/bash
2
#
3
# Test various instructions to check whether half<->full widening/narrowing
4
# works. The basic premise is to perform the same instruction with and
5
# without the widening/narrowing folded in and check if the results match.
6
#
7
# Note this doesn't currently diferentiate between signed/unsigned/bool,
8
# and just assumes int is signed (since unsigned is basically(ish) like
9
# signed but without sign extension)
10
#
11
# TODO probably good pick numeric src values that are better at triggering
12
# edge cases, while still not loosing precision in a full->half->full
13
# seqeuence.. but some instructions like absneg don't even appear to be
14
# subtlely wrong when you try to fold in a precision conversion.
15
#
16
# add '-v' arg to see the result values
17
18
set -e
19
20
#
21
# Templates for float->float instructions:
22
#
23
f2f_instrs=(
24
'add.f $dst, $src1, $src2'
25
'min.f $dst, $src1, $src2'
26
'min.f $dst, $src2, $src1'
27
'max.f $dst, $src1, $src2'
28
'max.f $dst, $src2, $src1'
29
'mul.f $dst, $src1, $src2'
30
'sign.f $dst, $src1'
31
'absneg.f $dst, \(neg\)$src1'
32
'absneg.f $dst, \(abs\)$src1'
33
'floor.f $dst, $src1'
34
'ceil.f $dst, $src1'
35
'rndne.f $dst, $src1'
36
'rndaz.f $dst, $src1'
37
'trunc.f $dst, $src1'
38
)
39
40
#
41
# Templates for float->int instructions:
42
#
43
f2i_instrs=(
44
'cmps.f.gt $dst, $src1, $src2'
45
'cmps.f.lt $dst, $src1, $src2'
46
'cmpv.f.gt $dst, $src1, $src2'
47
'cmpv.f.lt $dst, $src1, $src2'
48
)
49
50
#
51
# Templates for int->int instructions:
52
#
53
i2i_instrs=(
54
'add.u $dst, $src1, $src2'
55
'add.s $dst, $src1, $src2'
56
'sub.u $dst, $src1, $src2'
57
'sub.s $dst, $src1, $src2'
58
'cmps.f.gt $dst, $src1, $src2'
59
'cmps.f.lt $dst, $src1, $src2'
60
'min.u $dst, $src1, $src2'
61
'min.u $dst, $src2, $src1'
62
'min.s $dst, $src1, $src2'
63
'min.s $dst, $src2, $src1'
64
'max.u $dst, $src1, $src2'
65
'max.u $dst, $src2, $src1'
66
'max.s $dst, $src1, $src2'
67
'max.s $dst, $src2, $src1'
68
'absneg.s $dst, \(neg\)$src1'
69
'absneg.s $dst, \(abs\)$src1'
70
'and.b $dst, $src2, $src3'
71
'or.b $dst, $src1, $src2'
72
'not.b $dst, $src1'
73
'xor.b $dst, $src1, $src2'
74
'cmpv.u.gt $dst, $src1, $src2'
75
'cmpv.u.lt $dst, $src1, $src2'
76
'cmpv.s.gt $dst, $src1, $src2'
77
'cmpv.s.lt $dst, $src1, $src2'
78
'mul.u24 $dst, $src1, $src2'
79
'mul.s24 $dst, $src1, $src2'
80
'mull.u $dst, $src1, $src2'
81
'bfrev.b $dst, $src1'
82
'clz.s $dst, $src2'
83
'clz.b $dst, $src2'
84
'shl.b $dst, $src1, $src2'
85
'shr.b $dst, $src3, $src1'
86
'ashr.b $dst, $src3, $src1'
87
'mgen.b $dst, $src1, $src2'
88
'getbit.b $dst, $src3, $src2'
89
'setrm $dst, $src1'
90
'cbits.b $dst, $src3'
91
'shb $dst, $src1, $src2'
92
'msad $dst, $src1, $src2'
93
)
94
95
#
96
# Helper to expand instruction template:
97
#
98
expand() {
99
instr=$1
100
dst=$2
101
src1=$3
102
src2=$4
103
src3=$5
104
eval echo $instr
105
}
106
107
expand_test() {
108
instr=$1
109
110
echo '; control, half->half:'
111
expand $instr "hr1.x" "hr0.x" "hr0.y" "hr0.z"
112
echo '; test, full->half:'
113
expand $instr "hr1.y" "r1.x" "r1.y" "r1.z"
114
115
echo '; control, full->full:'
116
expand $instr "r2.x" "r1.x" "r1.y" "r1.z"
117
echo '; test, half->full:'
118
expand $instr "r2.y" "hr0.x" "hr0.y" "hr0.z"
119
120
echo "(rpt5)nop"
121
}
122
123
#
124
# Helpers to construct test program assembly:
125
#
126
header_asm() {
127
cat <<EOF
128
@localsize 1, 1, 1
129
@buf 4 ; g[0]
130
EOF
131
}
132
133
footer_asm() {
134
cat <<EOF
135
; dest offsets:
136
mov.u32u32 r3.x, 0
137
mov.u32u32 r3.y, 1
138
mov.u32u32 r3.z, 2
139
mov.u32u32 r3.w, 3
140
(rpt5)nop
141
142
; and store results:
143
stib.untyped.1d.u32.1 r2.x, r3.x, 0 ; control: full->full
144
stib.untyped.1d.u32.1 r2.y, r3.y, 0 ; test: half->full
145
stib.untyped.1d.u32.1 r2.z, r3.z, 0 ; control: half->half
146
stib.untyped.1d.u32.1 r2.w, r3.w, 0 ; test: full->half
147
(sy)nop
148
end
149
EOF
150
}
151
152
setup_asm_float() {
153
cat <<EOF
154
; hr0->hr1 (r0) avail for half, hr0 for src, hr1 for dst
155
; r1->r2 avail for full, r1 for src, r2 for dst
156
cov.f32f16 hr0.x, (1.0)
157
cov.f32f16 hr0.y, (2.0)
158
cov.f32f16 hr0.z, (3.0)
159
mov.f32f32 r1.x, (1.0)
160
mov.f32f32 r1.y, (2.0)
161
mov.f32f32 r1.z, (3.0)
162
(rpt5)nop
163
EOF
164
}
165
166
setup_asm_int() {
167
cat <<EOF
168
; hr0->hr1 (r0) avail for half, hr0 for src, hr1 for dst
169
; r1->r2 avail for full, r1 for src, r2 for dst
170
cov.s32s16 hr0.x, 1
171
cov.s32s16 hr0.y, -2
172
cov.s32s16 hr0.z, 3
173
mov.s32s32 r1.x, 1
174
mov.s32s32 r1.y, -2
175
mov.s32s32 r1.z, 3
176
(rpt5)nop
177
EOF
178
}
179
180
#
181
# Generate assembly code to test float->float opcode
182
#
183
f2f_asm() {
184
instr=$1
185
186
header_asm
187
setup_asm_float
188
expand_test $instr
189
190
cat <<EOF
191
; convert half results back to full:
192
cov.f16f32 r2.z, hr1.x
193
cov.f16f32 r2.w, hr1.y
194
EOF
195
196
footer_asm
197
}
198
199
#
200
# Generate assembly code to test float->int opcode
201
#
202
f2i_asm() {
203
instr=$1
204
205
header_asm
206
setup_asm_float
207
expand_test $instr
208
209
cat <<EOF
210
; convert half results back to full:
211
cov.s16s32 r2.z, hr1.x
212
cov.s16s32 r2.w, hr1.y
213
EOF
214
215
footer_asm
216
}
217
218
#
219
# Generate assembly code to test int->int opcode
220
#
221
i2i_asm() {
222
instr=$1
223
224
header_asm
225
setup_asm_int
226
expand_test $instr
227
228
cat <<EOF
229
; convert half results back to full:
230
cov.s16s32 r2.z, hr1.x
231
cov.s16s32 r2.w, hr1.y
232
EOF
233
234
footer_asm
235
}
236
237
238
#
239
# Helper to parse computerator output and print results:
240
#
241
check_results() {
242
str=`cat - | grep " " | head -1 | xargs`
243
244
if [ "$verbose" = "true" ]; then
245
echo $str
246
fi
247
248
# Split components of result buffer:
249
cf=$(echo $str | cut -f1 -d' ')
250
tf=$(echo $str | cut -f2 -d' ')
251
ch=$(echo $str | cut -f3 -d' ')
252
th=$(echo $str | cut -f4 -d' ')
253
254
# Sanity test, make sure the control results match:
255
if [ $cf != $ch ]; then
256
echo " FAIL: control results do not match! Half vs full op is not equivalent!"
257
echo " full=$cf half=$ch"
258
fi
259
260
# Compare test (with conversion folded) to control:
261
if [ $cf != $tf ]; then
262
echo " FAIL: half -> full widening result does not match control!"
263
echo " control=$cf result=$tf"
264
fi
265
if [ $ch != $th ]; then
266
echo " FAIL: full -> half narrowing result does not match control!"
267
echo " control=$ch result=$th"
268
fi
269
270
# HACK without a delay different invocations
271
# of computerator seem to somehow clobber each
272
# other.. which isn't great..
273
sleep 0.1
274
}
275
276
#
277
# Run the tests!
278
#
279
280
if [ "$1" = "-v" ]; then
281
verbose="true"
282
fi
283
284
IFS=""
285
for instr in ${f2f_instrs[@]}; do
286
echo "TEST: $instr"
287
f2f_asm $instr | ./computerator -g 1,1,1 | check_results
288
done
289
for instr in ${f2i_instrs[@]}; do
290
echo "TEST: $instr"
291
f2i_asm $instr | ./computerator -g 1,1,1 | check_results
292
done
293
for instr in ${i2i_instrs[@]}; do
294
echo "TEST: $instr"
295
i2i_asm $instr | ./computerator -g 1,1,1 | check_results
296
done
297
298
299