forked from suyu/suyu
implement lop3
This commit is contained in:
parent
b38d67d940
commit
8e8326595f
2 changed files with 55 additions and 0 deletions
|
@ -280,6 +280,19 @@ union Instruction {
|
||||||
BitField<56, 1, u64> invert_b;
|
BitField<56, 1, u64> invert_b;
|
||||||
} lop32i;
|
} lop32i;
|
||||||
|
|
||||||
|
union {
|
||||||
|
BitField<28, 8, u64> imm_lut28;
|
||||||
|
BitField<48, 8, u64> imm_lut48;
|
||||||
|
|
||||||
|
u32 GetImmLut28() const {
|
||||||
|
return static_cast<u32>(imm_lut28);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetImmLut48() const {
|
||||||
|
return static_cast<u32>(imm_lut48);
|
||||||
|
}
|
||||||
|
} lop3;
|
||||||
|
|
||||||
u32 GetImm20_19() const {
|
u32 GetImm20_19() const {
|
||||||
u32 imm{static_cast<u32>(imm20_19)};
|
u32 imm{static_cast<u32>(imm20_19)};
|
||||||
imm <<= 12;
|
imm <<= 12;
|
||||||
|
@ -650,6 +663,9 @@ public:
|
||||||
LOP_R,
|
LOP_R,
|
||||||
LOP_IMM,
|
LOP_IMM,
|
||||||
LOP32I,
|
LOP32I,
|
||||||
|
LOP3_C,
|
||||||
|
LOP3_R,
|
||||||
|
LOP3_IMM,
|
||||||
MOV_C,
|
MOV_C,
|
||||||
MOV_R,
|
MOV_R,
|
||||||
MOV_IMM,
|
MOV_IMM,
|
||||||
|
@ -872,6 +888,9 @@ private:
|
||||||
INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"),
|
INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"),
|
||||||
INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"),
|
INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"),
|
||||||
INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"),
|
INST("000001----------", Id::LOP32I, Type::ArithmeticIntegerImmediate, "LOP32I"),
|
||||||
|
INST("0000001---------", Id::LOP3_C, Type::ArithmeticInteger, "LOP3_C"),
|
||||||
|
INST("0101101111100---", Id::LOP3_R, Type::ArithmeticInteger, "LOP3_R"),
|
||||||
|
INST("0011110---------", Id::LOP3_IMM, Type::ArithmeticInteger, "LOP3_IMM"),
|
||||||
INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"),
|
INST("0100110001001---", Id::SHL_C, Type::Shift, "SHL_C"),
|
||||||
INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"),
|
INST("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"),
|
||||||
INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"),
|
INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"),
|
||||||
|
|
|
@ -849,6 +849,28 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteLop3Instruction(Register dest, const std::string& op_a, const std::string& op_b,
|
||||||
|
const std::string& op_c, const std::string& imm_lut) {
|
||||||
|
std::string result;
|
||||||
|
result += '(';
|
||||||
|
|
||||||
|
for (u32 i = 0; i < 32; ++i) {
|
||||||
|
std::string ix = std::to_string(i);
|
||||||
|
if (i)
|
||||||
|
result += '|';
|
||||||
|
result += "(((" + imm_lut + ">>(((" + op_c + ">>" + ix + ")&1)|((" + op_b + ">>" + ix +
|
||||||
|
")&1)<<1|((" + op_a + ">>" + ix + ")&1)<<2))&1)<<" + ix + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
result += ')';
|
||||||
|
|
||||||
|
LOG_DEBUG(HW_GPU, "LOP3 Shader code: {}", result);
|
||||||
|
|
||||||
|
if (dest != Tegra::Shader::Register::ZeroIndex) {
|
||||||
|
regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WriteTexsInstruction(const Instruction& instr, const std::string& coord,
|
void WriteTexsInstruction(const Instruction& instr, const std::string& coord,
|
||||||
const std::string& texture) {
|
const std::string& texture) {
|
||||||
// Add an extra scope and declare the texture coords inside to prevent
|
// Add an extra scope and declare the texture coords inside to prevent
|
||||||
|
@ -1297,6 +1319,20 @@ private:
|
||||||
instr.alu.lop.pred_result_mode, instr.alu.lop.pred48);
|
instr.alu.lop.pred_result_mode, instr.alu.lop.pred48);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OpCode::Id::LOP3_C:
|
||||||
|
case OpCode::Id::LOP3_R:
|
||||||
|
case OpCode::Id::LOP3_IMM: {
|
||||||
|
std::string op_c = regs.GetRegisterAsInteger(instr.gpr39);
|
||||||
|
std::string lut;
|
||||||
|
if (opcode->GetId() == OpCode::Id::LOP3_R) {
|
||||||
|
lut = '(' + std::to_string(instr.alu.lop3.GetImmLut28()) + ')';
|
||||||
|
} else {
|
||||||
|
lut = '(' + std::to_string(instr.alu.lop3.GetImmLut48()) + ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
WriteLop3Instruction(instr.gpr0, op_a, op_b, op_c, lut);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OpCode::Id::IMNMX_C:
|
case OpCode::Id::IMNMX_C:
|
||||||
case OpCode::Id::IMNMX_R:
|
case OpCode::Id::IMNMX_R:
|
||||||
case OpCode::Id::IMNMX_IMM: {
|
case OpCode::Id::IMNMX_IMM: {
|
||||||
|
|
Loading…
Reference in a new issue