mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-01-01 22:30:02 +01:00
rsx/asm: Add support for more opcodes and add tests for mixed block IO
This commit is contained in:
parent
13d66f324b
commit
ed397c5d67
|
|
@ -8,6 +8,32 @@
|
|||
|
||||
namespace rsx::assembler
|
||||
{
|
||||
static std::unordered_map<std::string, FP_opcode> s_opcode_lookup
|
||||
{
|
||||
// Arithmetic
|
||||
{ "NOP", RSX_FP_OPCODE_NOP },
|
||||
{ "MOV", RSX_FP_OPCODE_MOV },
|
||||
{ "ADD", RSX_FP_OPCODE_ADD },
|
||||
{ "MAD", RSX_FP_OPCODE_MAD },
|
||||
{ "FMA", RSX_FP_OPCODE_MAD },
|
||||
{ "DP3", RSX_FP_OPCODE_DP3 },
|
||||
{ "DP4", RSX_FP_OPCODE_DP4 },
|
||||
|
||||
// Pack-unpack operations are great for testing dependencies
|
||||
{ "PKH", RSX_FP_OPCODE_PK2 },
|
||||
{ "UPH", RSX_FP_OPCODE_UP2 },
|
||||
{ "PK16U", RSX_FP_OPCODE_PK16 },
|
||||
{ "UP16U", RSX_FP_OPCODE_UP16 },
|
||||
{ "PK8U", RSX_FP_OPCODE_PKB },
|
||||
{ "UP8U", RSX_FP_OPCODE_UPB },
|
||||
{ "PK8G", RSX_FP_OPCODE_PKG },
|
||||
{ "UP8G", RSX_FP_OPCODE_UPG },
|
||||
{ "PK8S", RSX_FP_OPCODE_PK4 },
|
||||
{ "UP8S", RSX_FP_OPCODE_UP4 },
|
||||
// TODO: Add more
|
||||
|
||||
};
|
||||
|
||||
Instruction* FPIR::load(const RegisterRef& ref, int operand, Instruction* prev)
|
||||
{
|
||||
Instruction* target = prev;
|
||||
|
|
@ -233,39 +259,15 @@ namespace rsx::assembler
|
|||
inst->bytecode[1] = s0.HEX; \
|
||||
} while (0)
|
||||
|
||||
if (op == "MOV")
|
||||
const auto found = s_opcode_lookup.find(op);
|
||||
if (found == s_opcode_lookup.end())
|
||||
{
|
||||
SET_OPCODE(RSX_FP_OPCODE_MOV);
|
||||
return;
|
||||
fmt::throw_exception("Unhandled instruction '%s'", op);
|
||||
}
|
||||
|
||||
if (op == "ADD")
|
||||
{
|
||||
SET_OPCODE(RSX_FP_OPCODE_ADD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op == "MAD" || op == "FMA")
|
||||
{
|
||||
SET_OPCODE(RSX_FP_OPCODE_MAD);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op == "UP4S")
|
||||
{
|
||||
SET_OPCODE(RSX_FP_OPCODE_UP4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (op == "PK4S")
|
||||
{
|
||||
SET_OPCODE(RSX_FP_OPCODE_PK4);
|
||||
return;
|
||||
}
|
||||
SET_OPCODE(found->second);
|
||||
|
||||
#undef SET_OPCODE
|
||||
|
||||
fmt::throw_exception("Unhandled instruction '%s'", op);
|
||||
};
|
||||
|
||||
std::string op, dst;
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace rsx::assembler
|
|||
|
||||
TEST(TestFPIR, RegisterAnnotationPass)
|
||||
{
|
||||
// Code snippet reads from R0 and R2, clobbers R0, R1, H0
|
||||
// Code snippet reads from R0, R1 and H4, clobbers R1, H0
|
||||
auto graph = CFG_from_source(R"(
|
||||
ADD R1, R0, R1;
|
||||
MOV H0, H4;
|
||||
|
|
@ -99,4 +99,34 @@ namespace rsx::assembler
|
|||
EXPECT_EQ(block.input_list[1].reg, R0);
|
||||
EXPECT_EQ(block.input_list[2].reg, R1);
|
||||
}
|
||||
|
||||
TEST(TestFPIR, RegisterAnnotationPass_MixedIO)
|
||||
{
|
||||
// Code snippet reads from R0, R1, clobbers R0, R1, H0.
|
||||
// The H2 read does not count because R1 is clobbered.
|
||||
auto graph = CFG_from_source(R"(
|
||||
ADD R1, R0, R1;
|
||||
PK8U R0, R1;
|
||||
MOV H0, H2;
|
||||
)");
|
||||
|
||||
ASSERT_EQ(graph.blocks.size(), 1);
|
||||
ASSERT_EQ(graph.blocks.front().instructions.size(), 3);
|
||||
|
||||
auto& block = graph.blocks.front();
|
||||
RSXFragmentProgram prog{};
|
||||
FP::RegisterAnnotationPass annotation_pass(prog);
|
||||
|
||||
annotation_pass.run(graph);
|
||||
|
||||
ASSERT_EQ(block.clobber_list.size(), 3);
|
||||
ASSERT_EQ(block.input_list.size(), 2);
|
||||
|
||||
EXPECT_EQ(block.clobber_list[0].reg, H0);
|
||||
EXPECT_EQ(block.clobber_list[1].reg, R0);
|
||||
EXPECT_EQ(block.clobber_list[2].reg, R1);
|
||||
|
||||
EXPECT_EQ(block.input_list[0].reg, R0);
|
||||
EXPECT_EQ(block.input_list[1].reg, R1);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue