gl_shader_decompiler: Implement RRO as a register move.

This commit is contained in:
bunnei 2018-06-01 00:03:23 -04:00
parent bdd68fc210
commit e54ea773fc
2 changed files with 18 additions and 9 deletions

View File

@ -297,8 +297,10 @@ public:
FMUL_R, FMUL_R,
FMUL_IMM, FMUL_IMM,
FMUL32_IMM, FMUL32_IMM,
MUFU, // Multi-Function Operator MUFU, // Multi-Function Operator
RRO, // Range Reduction Operator RRO_C, // Range Reduction Operator
RRO_R,
RRO_IMM,
F2F_C, F2F_C,
F2F_R, F2F_R,
F2F_IMM, F2F_IMM,
@ -459,7 +461,9 @@ private:
INST("0011100-01101---", Id::FMUL_IMM, Type::Arithmetic, "FMUL_IMM"), INST("0011100-01101---", Id::FMUL_IMM, Type::Arithmetic, "FMUL_IMM"),
INST("00011110--------", Id::FMUL32_IMM, Type::Arithmetic, "FMUL32_IMM"), INST("00011110--------", Id::FMUL32_IMM, Type::Arithmetic, "FMUL32_IMM"),
INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"), INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
INST("0101110010010---", Id::RRO, Type::Arithmetic, "RRO"), INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
INST("0011100-10010---", Id::RRO_IMM, Type::Arithmetic, "RRO_IMM"),
INST("0100110010101---", Id::F2F_C, Type::Conversion, "F2F_C"), INST("0100110010101---", Id::F2F_C, Type::Conversion, "F2F_C"),
INST("0101110010101---", Id::F2F_R, Type::Conversion, "F2F_R"), INST("0101110010101---", Id::F2F_R, Type::Conversion, "F2F_R"),
INST("0011100-10101---", Id::F2F_IMM, Type::Conversion, "F2F_IMM"), INST("0011100-10101---", Id::F2F_IMM, Type::Conversion, "F2F_IMM"),

View File

@ -792,8 +792,13 @@ private:
1, 1); 1, 1);
break; break;
} }
case OpCode::Id::RRO: { case OpCode::Id::RRO_C:
NGLOG_DEBUG(HW_GPU, "Skipping RRO instruction"); case OpCode::Id::RRO_R:
case OpCode::Id::RRO_IMM: {
// Currently RRO is only implemented as a register move.
// Usage of `abs_b` and `negate_b` here should also be correct.
regs.SetRegisterToFloat(instr.gpr0, 0, op_b, 1, 1);
NGLOG_WARNING(HW_GPU, "RRO instruction is incomplete");
break; break;
} }
default: { default: {
@ -897,8 +902,8 @@ private:
const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20); const std::string op_b = regs.GetRegisterAsFloat(instr.gpr20);
const std::string sampler = GetSampler(instr.sampler); const std::string sampler = GetSampler(instr.sampler);
const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");"; const std::string coord = "vec2 coords = vec2(" + op_a + ", " + op_b + ");";
// Add an extra scope and declare the texture coords inside to prevent overwriting // Add an extra scope and declare the texture coords inside to prevent
// them in case they are used as outputs of the texs instruction. // overwriting them in case they are used as outputs of the texs instruction.
shader.AddLine("{"); shader.AddLine("{");
++shader.scope; ++shader.scope;
shader.AddLine(coord); shader.AddLine(coord);
@ -961,8 +966,8 @@ private:
'(' + predicate + ") " + combiner + " (" + second_pred + ')'); '(' + predicate + ") " + combiner + " (" + second_pred + ')');
if (instr.fsetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) { if (instr.fsetp.pred0 != static_cast<u64>(Pred::UnusedIndex)) {
// Set the secondary predicate to the result of !Predicate OP SecondPredicate, if // Set the secondary predicate to the result of !Predicate OP SecondPredicate,
// enabled // if enabled
SetPredicate(instr.fsetp.pred0, SetPredicate(instr.fsetp.pred0,
"!(" + predicate + ") " + combiner + " (" + second_pred + ')'); "!(" + predicate + ") " + combiner + " (" + second_pred + ')');
} }