Merge pull request #1760 from ReinUsesLisp/r2p
gl_shader_decompiler: Implement R2P_IMM
This commit is contained in:
		@@ -368,6 +368,11 @@ enum class HalfPrecision : u64 {
 | 
			
		||||
    FMZ = 2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class R2pMode : u64 {
 | 
			
		||||
    Pr = 0,
 | 
			
		||||
    Cc = 1,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class IpaInterpMode : u64 {
 | 
			
		||||
    Linear = 0,
 | 
			
		||||
    Perspective = 1,
 | 
			
		||||
@@ -856,6 +861,12 @@ union Instruction {
 | 
			
		||||
        BitField<39, 3, u64> pred39;
 | 
			
		||||
    } hsetp2;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<40, 1, R2pMode> mode;
 | 
			
		||||
        BitField<41, 2, u64> byte;
 | 
			
		||||
        BitField<20, 7, u64> immediate_mask;
 | 
			
		||||
    } r2p;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<39, 3, u64> pred39;
 | 
			
		||||
        BitField<42, 1, u64> neg_pred;
 | 
			
		||||
@@ -1383,6 +1394,7 @@ public:
 | 
			
		||||
        PSETP,
 | 
			
		||||
        PSET,
 | 
			
		||||
        CSETP,
 | 
			
		||||
        R2P_IMM,
 | 
			
		||||
        XMAD_IMM,
 | 
			
		||||
        XMAD_CR,
 | 
			
		||||
        XMAD_RC,
 | 
			
		||||
@@ -1412,6 +1424,7 @@ public:
 | 
			
		||||
        HalfSetPredicate,
 | 
			
		||||
        PredicateSetPredicate,
 | 
			
		||||
        PredicateSetRegister,
 | 
			
		||||
        RegisterSetPredicate,
 | 
			
		||||
        Conversion,
 | 
			
		||||
        Xmad,
 | 
			
		||||
        Unknown,
 | 
			
		||||
@@ -1649,6 +1662,7 @@ private:
 | 
			
		||||
            INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
 | 
			
		||||
            INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
 | 
			
		||||
            INST("010100001010----", Id::CSETP, Type::PredicateSetPredicate, "CSETP"),
 | 
			
		||||
            INST("0011100-11110---", Id::R2P_IMM, Type::RegisterSetPredicate, "R2P_IMM"),
 | 
			
		||||
            INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
 | 
			
		||||
            INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
 | 
			
		||||
            INST("010100010-------", Id::XMAD_RC, Type::Xmad, "XMAD_RC"),
 | 
			
		||||
 
 | 
			
		||||
@@ -3315,6 +3315,34 @@ private:
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case OpCode::Type::RegisterSetPredicate: {
 | 
			
		||||
            UNIMPLEMENTED_IF(instr.r2p.mode != Tegra::Shader::R2pMode::Pr);
 | 
			
		||||
 | 
			
		||||
            const std::string apply_mask = [&]() {
 | 
			
		||||
                switch (opcode->get().GetId()) {
 | 
			
		||||
                case OpCode::Id::R2P_IMM:
 | 
			
		||||
                    return std::to_string(instr.r2p.immediate_mask);
 | 
			
		||||
                default:
 | 
			
		||||
                    UNREACHABLE();
 | 
			
		||||
                }
 | 
			
		||||
            }();
 | 
			
		||||
            const std::string mask = '(' + regs.GetRegisterAsInteger(instr.gpr8, 0, false) +
 | 
			
		||||
                                     " >> " + std::to_string(instr.r2p.byte) + ')';
 | 
			
		||||
 | 
			
		||||
            constexpr u64 programmable_preds = 7;
 | 
			
		||||
            for (u64 pred = 0; pred < programmable_preds; ++pred) {
 | 
			
		||||
                const auto shift = std::to_string(1 << pred);
 | 
			
		||||
 | 
			
		||||
                shader.AddLine("if ((" + apply_mask + " & " + shift + ") != 0) {");
 | 
			
		||||
                ++shader.scope;
 | 
			
		||||
 | 
			
		||||
                SetPredicate(pred, '(' + mask + " & " + shift + ") != 0");
 | 
			
		||||
 | 
			
		||||
                --shader.scope;
 | 
			
		||||
                shader.AddLine('}');
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case OpCode::Type::FloatSet: {
 | 
			
		||||
            const std::string op_a = GetOperandAbsNeg(regs.GetRegisterAsFloat(instr.gpr8),
 | 
			
		||||
                                                      instr.fset.abs_a != 0, instr.fset.neg_a != 0);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user