mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-15 22:54:00 +00:00
shader/memory: Implement LDL.S16 and LDS.S16
This commit is contained in:
parent
05df4a8c94
commit
96638f57c9
1 changed files with 23 additions and 12 deletions
|
@ -22,6 +22,7 @@ using Tegra::Shader::Attribute;
|
||||||
using Tegra::Shader::Instruction;
|
using Tegra::Shader::Instruction;
|
||||||
using Tegra::Shader::OpCode;
|
using Tegra::Shader::OpCode;
|
||||||
using Tegra::Shader::Register;
|
using Tegra::Shader::Register;
|
||||||
|
using Tegra::Shader::StoreType;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
@ -61,6 +62,13 @@ u32 GetMemorySize(Tegra::Shader::UniformType uniform_type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Node Sign16Extend(Node value) {
|
||||||
|
Node sign = Operation(OperationCode::UBitwiseAnd, value, Immediate(1U << 15));
|
||||||
|
Node is_sign = Operation(OperationCode::LogicalUEqual, std::move(sign), Immediate(1U << 15));
|
||||||
|
Node extend = Operation(OperationCode::Select, is_sign, Immediate(0xFFFF0000), Immediate(0));
|
||||||
|
return Operation(OperationCode::UBitwiseOr, std::move(value), std::move(extend));
|
||||||
|
}
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
||||||
|
@ -139,23 +147,26 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
||||||
const auto GetMemory = [&](s32 offset) {
|
const auto GetMemory = [&](s32 offset) {
|
||||||
ASSERT(offset % 4 == 0);
|
ASSERT(offset % 4 == 0);
|
||||||
const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
|
const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset);
|
||||||
const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8),
|
const Node address =
|
||||||
immediate_offset);
|
Operation(OperationCode::IAdd, GetRegister(instr.gpr8), immediate_offset);
|
||||||
return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address)
|
return opcode->get().GetId() == OpCode::Id::LD_S ? GetSharedMemory(address)
|
||||||
: GetLocalMemory(address);
|
: GetLocalMemory(address);
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (instr.ldst_sl.type.Value()) {
|
switch (instr.ldst_sl.type.Value()) {
|
||||||
case Tegra::Shader::StoreType::Bits32:
|
case StoreType::Signed16:
|
||||||
case Tegra::Shader::StoreType::Bits64:
|
SetRegister(bb, instr.gpr0, Sign16Extend(GetMemory(0)));
|
||||||
case Tegra::Shader::StoreType::Bits128: {
|
break;
|
||||||
const u32 count = [&]() {
|
case StoreType::Bits32:
|
||||||
|
case StoreType::Bits64:
|
||||||
|
case StoreType::Bits128: {
|
||||||
|
const u32 count = [&] {
|
||||||
switch (instr.ldst_sl.type.Value()) {
|
switch (instr.ldst_sl.type.Value()) {
|
||||||
case Tegra::Shader::StoreType::Bits32:
|
case StoreType::Bits32:
|
||||||
return 1;
|
return 1;
|
||||||
case Tegra::Shader::StoreType::Bits64:
|
case StoreType::Bits64:
|
||||||
return 2;
|
return 2;
|
||||||
case Tegra::Shader::StoreType::Bits128:
|
case StoreType::Bits128:
|
||||||
return 4;
|
return 4;
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
@ -274,14 +285,14 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, u32 pc) {
|
||||||
: &ShaderIR::SetSharedMemory;
|
: &ShaderIR::SetSharedMemory;
|
||||||
|
|
||||||
switch (instr.ldst_sl.type.Value()) {
|
switch (instr.ldst_sl.type.Value()) {
|
||||||
case Tegra::Shader::StoreType::Bits128:
|
case StoreType::Bits128:
|
||||||
(this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3));
|
(this->*set_memory)(bb, GetAddress(12), GetRegister(instr.gpr0.Value() + 3));
|
||||||
(this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2));
|
(this->*set_memory)(bb, GetAddress(8), GetRegister(instr.gpr0.Value() + 2));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Tegra::Shader::StoreType::Bits64:
|
case StoreType::Bits64:
|
||||||
(this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1));
|
(this->*set_memory)(bb, GetAddress(4), GetRegister(instr.gpr0.Value() + 1));
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case Tegra::Shader::StoreType::Bits32:
|
case StoreType::Bits32:
|
||||||
(this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
|
(this->*set_memory)(bb, GetAddress(0), GetRegister(instr.gpr0));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue