2 * Copyright © 2016 Broadcom
3 * Copyright © 2020 Google LLC
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 #include "util/macros.h"
29 #include "instr-a3xx.h"
31 #define INSTR_6XX(i, d) { .gpu_id = 630, .instr = #i, .expected = d }
33 static const struct test
{
39 INSTR_6XX(00000000_00000000
, "nop"),
40 INSTR_6XX(00000200_00000000
, "(rpt2)nop"),
41 INSTR_6XX(03000000_00000000
, "end"),
42 INSTR_6XX(00800000_00000004
, "br p0.x, #4"),
43 INSTR_6XX(00900000_00000003
, "br !p0.x, #3"),
44 INSTR_6XX(03820000_00000015
, "shps #21"), /* emit */
45 INSTR_6XX(04021000_00000000
, "(ss)shpe"), /* cut */
46 INSTR_6XX(02820000_00000014
, "getone #20"), /* kill p0.x */
49 INSTR_6XX(20244000_00000020
, "mov.f32f32 r0.x, c8.x"),
50 INSTR_6XX(20200000_00000020
, "mov.f16f16 hr0.x, hc8.x"),
51 INSTR_6XX(20150000_00000000
, "cov.s32s16 hr0.x, r0.x"),
52 INSTR_6XX(20156004_00000c11
, "(ul)mov.s32s32 r1.x, c<a0.x + 17>"),
53 INSTR_6XX(201100f4_00000000
, "mova a0.x, hr0.x"),
54 INSTR_6XX(20244905_00000410
, "(rpt1)mov.f32f32 r1.y, (r)c260.x"),
57 INSTR_6XX(40104002_0c210001
, "add.f hr0.z, r0.y, c<a0.x + 33>"),
58 INSTR_6XX(40b80804_10408004
, "(nop3) cmps.f.lt r1.x, (abs)r1.x, c16.x"),
59 INSTR_6XX(47308a02_00002000
, "(rpt2)bary.f (ei)r0.z, (r)0, r0.x"),
60 INSTR_6XX(43480801_00008001
, "(nop3) absneg.s hr0.y, (abs)hr0.y"),
63 INSTR_6XX(66000000_10421041
, "sel.f16 hr0.x, hc16.y, hr0.x, hc16.z"),
64 INSTR_6XX(64848109_109a9099
, "(rpt1)sel.b32 r2.y, c38.y, (r)r2.y, c38.z"),
65 INSTR_6XX(64810904_30521036
, "(rpt1)sel.b32 r1.x, (r)c13.z, r0.z, (r)c20.z"),
66 INSTR_6XX(64818902_20041032
, "(rpt1)sel.b32 r0.z, (r)c12.z, r0.w, (r)r1.x"),
67 INSTR_6XX(63820005_10315030
, "mad.f32 r1.y, (neg)c12.x, r1.x, c12.y"),
68 INSTR_6XX(62050009_00091000
, "mad.u24 r2.y, c0.x, r2.z, r2.y"),
71 INSTR_6XX(8010000a_00000003
, "rcp r2.z, r0.w"),
74 INSTR_6XX(a2802f00_00000001
, "getsize (u16)(xyzw)hr0.x, r0.x, t#0"),
77 INSTR_6XX(c0c00000_00000000
, "stg.f16 g[hr0.x], hr0.x, hr0.x"),
78 INSTR_6XX(c1100000_c1000000
, "stl.f16 l[0], hr0.x, hr48.y"),
79 INSTR_6XX(c0260000_0063c200
, "resinfo.untyped.2d.u32.1 r0.x, r0.x, 0"), /* resinfo.u32.2d.mode0.base0 r0.x, 0 */
80 INSTR_6XX(c0260000_0063c000
, "resinfo.untyped.1d.u32.1 r0.x, r0.x, 0"), /* resinfo.u32.1d.mode0.base0 r0.x, 0 */
83 INSTR_6XX(42b400f8_20010004
, "cmps.s.eq p0.x, r1.x, 1"),
84 INSTR_6XX(02800000_00000000
, "kill p0.x"),
87 INSTR_6XX(40100007_68000008
, "add.f r1.w, r2.x, (neg)(0.0)"),
88 INSTR_6XX(40100007_68010008
, "add.f r1.w, r2.x, (neg)(0.5)"),
89 INSTR_6XX(40100007_68020008
, "add.f r1.w, r2.x, (neg)(1.0)"),
90 INSTR_6XX(40100007_68030008
, "add.f r1.w, r2.x, (neg)(2.0)"),
91 INSTR_6XX(40100007_68040008
, "add.f r1.w, r2.x, (neg)(e)"),
92 INSTR_6XX(40100007_68050008
, "add.f r1.w, r2.x, (neg)(pi)"),
93 INSTR_6XX(40100007_68060008
, "add.f r1.w, r2.x, (neg)(1/pi)"),
94 INSTR_6XX(40100007_68070008
, "add.f r1.w, r2.x, (neg)(1/log2(e))"),
95 INSTR_6XX(40100007_68080008
, "add.f r1.w, r2.x, (neg)(log2(e))"),
96 INSTR_6XX(40100007_68090008
, "add.f r1.w, r2.x, (neg)(1/log2(10))"),
97 INSTR_6XX(40100007_680a0008
, "add.f r1.w, r2.x, (neg)(log2(10))"),
98 INSTR_6XX(40100007_680b0008
, "add.f r1.w, r2.x, (neg)(4.0)"),
100 /* LDC. Our disasm differs greatly from qcom here, and we've got some
101 * important info they lack(?!), but same goes the other way.
103 /* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.uniform_fragment */
104 INSTR_6XX(c0260000_00c78040
, "ldc.offset0.1 r0.x, r0.x, 0"), /* ldc.1.mode1.base0 r0.x, 0, r0.x */
105 INSTR_6XX(c0260201_00c78040
, "ldc.offset0.1 r0.y, r0.x, 1"), /* ldc.1.mode1.base0 r0.y, 0, r0.y */
106 /* dEQP-GLES31.functional.shaders.opaque_type_indexing.ubo.dynamically_uniform_fragment */
107 INSTR_6XX(c0260000_00c78080
, "ldc.offset0.1 r0.x, r0.x, 0"), /* ldc.1.mode2.base0 r0.x, 0, r0.x */
108 INSTR_6XX(c0260201_00c78080
, "ldc.offset0.1 r0.y, r0.x, 1"), /* ldc.1.mode2.base0 r0.y, 0, r0.y */
109 /* custom shaders, loading .x, .y, .z, .w from an array of vec4 in block 0 */
110 INSTR_6XX(c0260000_00478000
, "ldc.offset0.1 r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
111 INSTR_6XX(c0260000_00478200
, "ldc.offset1.1 r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
112 INSTR_6XX(c0260000_00478400
, "ldc.offset2.1 r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
113 INSTR_6XX(c0260000_00478600
, "ldc.offset3.1 r0.x, r0.x, 0"), /* ldc.1.mode0.base0 r0.x, r0.x, 0 */
115 /* dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.const_literal.fragment.sampler2d */
116 INSTR_6XX(a0c01f04_0cc00005
, "sam (f32)(xyzw)r1.x, r0.z, s#6, t#6"),
117 /* dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.uniform.fragment.sampler2d (looks like maybe the compiler didn't figure out */
118 INSTR_6XX(a0c81f07_0100000b
, "sam.s2en (f32)(xyzw)r1.w, r1.y, hr2.x"), /* sam.s2en.mode0 (f32)(xyzw)r1.w, r1.y, hr2.x */
119 /* dEQP-GLES31.functional.shaders.opaque_type_indexing.sampler.dynamically_uniform.fragment.sampler2d */
120 INSTR_6XX(a0c81f07_8100000b
, "sam.s2en.uniform (f32)(xyzw)r1.w, r1.y, hr2.x"), /* sam.s2en.mode4 (f32)(xyzw)r1.w, r1.y, hr2.x */
126 for (int len
= strlen(string
); len
> 0 && string
[len
- 1] == '\n'; len
--)
131 main(int argc
, char **argv
)
134 const int output_size
= 4096;
135 char *disasm_output
= malloc(output_size
);
136 FILE *fdisasm
= fmemopen(disasm_output
, output_size
, "w+");
138 fprintf(stderr
, "failed to fmemopen\n");
142 for (int i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
143 const struct test
*test
= &tests
[i
];
144 printf("Testing a%d %s: \"%s\"...\n",
145 test
->gpu_id
, test
->instr
, test
->expected
);
148 memset(disasm_output
, 0, output_size
);
151 strtoll(&test
->instr
[9], NULL
, 16),
152 strtoll(&test
->instr
[0], NULL
, 16),
154 disasm_a3xx(code
, ARRAY_SIZE(code
), 0, fdisasm
, test
->gpu_id
);
159 if (strcmp(disasm_output
, test
->expected
) != 0) {
161 printf(" Expected: \"%s\"\n", test
->expected
);
162 printf(" Got: \"%s\"\n", disasm_output
);