mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-24 20:20:31 +01:00
panvk: Add tests for ls tracker behavior in cs_loop
Reviewed-by: Boris Brezillon <boris.brezillon@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/35436>
This commit is contained in:
parent
cdedd04640
commit
f9ed719c6a
1 changed files with 197 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright 2025 Collabora Ltd
|
||||
* Copyright (C) 2025 Arm Ltd.
|
||||
* SPDX-License-Identifier: MIT
|
||||
*/
|
||||
|
||||
|
|
@ -138,3 +139,199 @@ TEST_F(CsBuilderTest, maybe_early_patch)
|
|||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched, ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If inside the loop no register is used that is getting loaded at the moment,
|
||||
* do not emit a WAIT on continue / going back to start. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_unrelated_inside)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index r1 = cs_reg32(&b, 1);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_while(&b, MALI_CS_CONDITION_ALWAYS, cs_undef()) {
|
||||
cs_add32(&b, r1, r1, 0x0);
|
||||
cs_break(&b);
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x1001010000000000, /* ADD32 r1, r1, #0x0 */
|
||||
0x1600000060000001, /* BRANCH al, r0, #1 */
|
||||
0x160000006000fffd, /* BRANCH al, r0, #-3 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If a load is started inside the loop it has to be waited for after the loop. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_load_only_inside_if)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_while(&b, MALI_CS_CONDITION_ALWAYS, cs_undef()) {
|
||||
cs_if(&b, MALI_CS_CONDITION_LESS, r0) {
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
}
|
||||
cs_break(&b);
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x1600000050000001, /* BRANCH ge, r0, #1 */
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x1600000060000002, /* BRANCH al, r0, #2 */
|
||||
/* This WAIT is unnecessary because the loop body doesn't use r0. */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x160000006000fffb, /* BRANCH al, r0, #-5 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If a load is started inside the loop with a continue in the if, it has to be
|
||||
* waited for on continue. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_load_only_continue_inside_if)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_add32(&b, r0, r0, 0x0);
|
||||
cs_while(&b, MALI_CS_CONDITION_ALWAYS, cs_undef()) {
|
||||
cs_if(&b, MALI_CS_CONDITION_LESS, cs_reg32(&b, 1)) {
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_continue(&b);
|
||||
}
|
||||
cs_break(&b);
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x1000000000000000, /* ADD32 r0, r0, #0x0 */
|
||||
0x1600010050000003, /* BRANCH ge, r1, #3 */
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x160000006000fffc, /* BRANCH al, r0, #-4 */
|
||||
0x1600000060000001, /* BRANCH al, r1, #1 */
|
||||
0x160000006000fffa, /* BRANCH al, r0, #-6 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If a load is started inside the loop with a break in the if, it has to be
|
||||
* waited for after the loop. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_load_only_break_inside_if)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_add32(&b, r0, r0, 0x0);
|
||||
cs_while(&b, MALI_CS_CONDITION_ALWAYS, cs_undef()) {
|
||||
cs_if(&b, MALI_CS_CONDITION_LESS, cs_reg32(&b, 1)) {
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_break(&b);
|
||||
}
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x1000000000000000, /* ADD32 r0, r0, #0x0 */
|
||||
0x1600010050000002, /* BRANCH ge, r1, #2 */
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x1600000060000002, /* BRANCH al, r0, #2 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x160000006000fffb, /* BRANCH al, r0, #-5 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If a register is loaded inside the loop, that was already getting loaded
|
||||
* when the loop began, there is no need to add a WAIT on continue. If that
|
||||
* register is used again after the loop, a WAIT has to be added. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_load_same_inside)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_while(&b, MALI_CS_CONDITION_ALWAYS, cs_undef()) {
|
||||
cs_add32(&b, r0, r0, 0x0);
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_if(&b, MALI_CS_CONDITION_LESS, cs_reg32(&b, 1)) {
|
||||
cs_break(&b);
|
||||
}
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x1000000000000000, /* ADD32 r0, r0, #0x0 */
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x1600010050000001, /* BRANCH ge, r1, #1 */
|
||||
0x1600000060000001, /* BRANCH al, r0, #1 */
|
||||
0x160000006000fffa, /* BRANCH al, r0, #-6 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
||||
/* If the register that is used and loaded in the loop body is also used as the
|
||||
* condition, we need to WAIT on continue because the WAIT for the condition is
|
||||
* emitted before the loop body. */
|
||||
TEST_F(CsBuilderTest, loop_ls_tracker_load_same_inside_use_as_cond)
|
||||
{
|
||||
struct cs_index r0 = cs_reg32(&b, 0);
|
||||
struct cs_index addr = cs_reg64(&b, 10);
|
||||
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_while(&b, MALI_CS_CONDITION_LESS, r0) {
|
||||
cs_add32(&b, r0, r0, 0x0);
|
||||
cs_load32_to(&b, r0, addr, 0x0);
|
||||
cs_if(&b, MALI_CS_CONDITION_LESS, cs_reg32(&b, 1)) {
|
||||
cs_break(&b);
|
||||
}
|
||||
}
|
||||
cs_add32(&b, r0, r0, 0xab);
|
||||
cs_finish(&b);
|
||||
|
||||
uint64_t expected_patched[] = {
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x1600000050000006, /* BRANCH ge, r0, #6 */
|
||||
0x1000000000000000, /* ADD32 r0, r0, #0x0 */
|
||||
0x14000a0000010000, /* LOAD_MULTIPLE r0, addr, #0x0 */
|
||||
0x1600010050000001, /* BRANCH ge, r1, #1 */
|
||||
0x1600000060000002, /* BRANCH al, r0, #2 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x160000004000fffa, /* BRANCH lt, r0, #-6 */
|
||||
0x0300000000010000, /* WAIT #0x1 */
|
||||
0x10000000000000ab, /* ADD32 r0, r0, #0xab */
|
||||
};
|
||||
EXPECT_EQ(b.root_chunk.size, ARRAY_SIZE(expected_patched));
|
||||
EXPECT_U64_ARRAY_EQUAL(output, expected_patched,
|
||||
ARRAY_SIZE(expected_patched));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue