|
|
|
@@ -20328,6 +20328,57 @@ TestCase ScalarBrevB32PreservesScc() {
|
|
|
|
|
O::V_MOV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestCase ScalarSextI16Captured() {
|
|
|
|
|
using O = ShaderOpcode;
|
|
|
|
|
TestCase test;
|
|
|
|
|
test.name = "ScalarSextI16Captured";
|
|
|
|
|
constexpr u32 wave_size = 64, high = 0x80000001u;
|
|
|
|
|
test.initial = {0xdead0000u, 0xabcd7fffu, 0x12348000u, 0xabcfffffu};
|
|
|
|
|
test.expected = test.initial;
|
|
|
|
|
auto &code = test.code;
|
|
|
|
|
for (u32 i = 0; i < 4u; ++i) {
|
|
|
|
|
const auto extended = static_cast<u32>(static_cast<int32_t>(static_cast<int16_t>(test.initial[i])));
|
|
|
|
|
for (const bool scc : {false, true}) {
|
|
|
|
|
AppendVMovU32(&code, 30, i * 4u);
|
|
|
|
|
AppendBufferLoadDword(&code, 3, 30);
|
|
|
|
|
code.push_back(EncodeVop1(0x02, 11, Vgpr(3)));
|
|
|
|
|
AppendSMovLiteral(&code, 107, high);
|
|
|
|
|
code.push_back(EncodeSopc(0x06, InlineU32(scc ? 1u : 0u), InlineU32(1)));
|
|
|
|
|
code.push_back(EncodeSop1(0x04, 126, 128)); // Scalar operations execute with empty EXEC.
|
|
|
|
|
code.push_back(0xbeea1a0bu); // Captured s_sext_i32_i16 vcc_lo, s11.
|
|
|
|
|
code.push_back(EncodeSMovB32(20, 106));
|
|
|
|
|
code.push_back(EncodeSMovB32(21, 107));
|
|
|
|
|
code.push_back(EncodeSMovB32(22, 253));
|
|
|
|
|
code.push_back(EncodeSop1(0x04, 126, 193));
|
|
|
|
|
AppendVMovU32(&code, 1, 1);
|
|
|
|
|
code.push_back(EncodeVop2(0x01, 2, InlineU32(0), 1));
|
|
|
|
|
const u32 expected[] = {extended, high, scc ? 1u : 0u};
|
|
|
|
|
for (u32 word = 0; word < 3u; ++word) {
|
|
|
|
|
AppendStoreSgprAtLaneDwordOffset(&code, 20u + word, 0, test.expected.size());
|
|
|
|
|
test.expected.insert(test.expected.end(), wave_size, expected[word]);
|
|
|
|
|
}
|
|
|
|
|
AppendStoreVgprAtLaneDwordOffset(&code, 2, 0, test.expected.size());
|
|
|
|
|
const uint64_t mask = (uint64_t{high} << 32u) | extended;
|
|
|
|
|
for (u32 lane = 0; lane < wave_size; ++lane)
|
|
|
|
|
test.expected.push_back(static_cast<u32>((mask >> lane) & 1u));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
AppendEnd(&code);
|
|
|
|
|
test.initial.resize(test.expected.size());
|
|
|
|
|
test.opcodes = {O::BUFFER_LOAD_DWORD, O::V_READFIRSTLANE_B32, O::S_MOV_B32,
|
|
|
|
|
O::S_MOV_B64, O::S_CMP_EQ_U32, O::S_SEXT_I32_I16,
|
|
|
|
|
O::V_CNDMASK_B32, O::V_MOV_B32, O::V_ADD_NC_U32,
|
|
|
|
|
O::V_LSHLREV_B32, O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
|
|
|
|
test.decoded_counts = {{"S_SEXT_I32_I16", 8u}};
|
|
|
|
|
test.required_spirv = {"OpBitFieldSExtract"};
|
|
|
|
|
test.compute_info.threads_num[0] = wave_size;
|
|
|
|
|
test.compute_info.threads_num[1] = test.compute_info.threads_num[2] = 1;
|
|
|
|
|
test.compute_info.thread_ids_num = 1;
|
|
|
|
|
test.compute_info.wave_size = wave_size;
|
|
|
|
|
test.has_compute_info = true;
|
|
|
|
|
return test;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TestCase ScalarBrevB64OperandsAndMasks(u32 wave_size) {
|
|
|
|
|
using O = ShaderOpcode;
|
|
|
|
|
TestCase test;
|
|
|
|
@@ -35081,6 +35132,7 @@ std::vector<TestCase> MakeCases() {
|
|
|
|
|
AddCase(ScalarBitcmpB64DynamicOperands);
|
|
|
|
|
AddCase(ScalarBitcmpB64IntegerConstants);
|
|
|
|
|
AddCase(ScalarBrevB32PreservesScc);
|
|
|
|
|
AddCase(ScalarSextI16Captured);
|
|
|
|
|
cases.push_back(ScalarBrevB64OperandsAndMasks(32));
|
|
|
|
|
cases.push_back(ScalarBrevB64OperandsAndMasks(64));
|
|
|
|
|
AddCase(ScalarBfeI32CapturedRawSignExtends);
|
|
|
|
@@ -40720,6 +40772,11 @@ int main(int argc, char **argv) {
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (argc == 2 && std::strcmp(argv[1], "--scalar-sext-only") == 0) {
|
|
|
|
|
VulkanHarness vulkan;
|
|
|
|
|
RunCase(&vulkan, ScalarSextI16Captured());
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (argc == 2 && std::strcmp(argv[1], "--flat-d16-only") == 0) {
|
|
|
|
|
VulkanHarness vulkan;
|
|
|
|
|
RunCase(&vulkan, FlatLoadDlcCaptured(32));
|
|
|
|
|