Merge pull request #1156 from Lakumakkara/lop3
gl_shader_decompiler: Implement LOP3
This commit is contained in:
		
						commit
						232b0d9d2a
					
				@ -280,6 +280,19 @@ union Instruction {
 | 
			
		||||
            BitField<56, 1, u64> invert_b;
 | 
			
		||||
        } 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 imm{static_cast<u32>(imm20_19)};
 | 
			
		||||
            imm <<= 12;
 | 
			
		||||
@ -650,6 +663,9 @@ public:
 | 
			
		||||
        LOP_R,
 | 
			
		||||
        LOP_IMM,
 | 
			
		||||
        LOP32I,
 | 
			
		||||
        LOP3_C,
 | 
			
		||||
        LOP3_R,
 | 
			
		||||
        LOP3_IMM,
 | 
			
		||||
        MOV_C,
 | 
			
		||||
        MOV_R,
 | 
			
		||||
        MOV_IMM,
 | 
			
		||||
@ -872,6 +888,9 @@ private:
 | 
			
		||||
            INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"),
 | 
			
		||||
            INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"),
 | 
			
		||||
            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("0101110001001---", Id::SHL_R, Type::Shift, "SHL_R"),
 | 
			
		||||
            INST("0011100-01001---", Id::SHL_IMM, Type::Shift, "SHL_IMM"),
 | 
			
		||||
 | 
			
		||||
@ -849,6 +849,33 @@ 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) {
 | 
			
		||||
        if (dest == Tegra::Shader::Register::ZeroIndex) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        static constexpr std::array<const char*, 32> shift_amounts = {
 | 
			
		||||
            "0",  "1",  "2",  "3",  "4",  "5",  "6",  "7",  "8",  "9",  "10",
 | 
			
		||||
            "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21",
 | 
			
		||||
            "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"};
 | 
			
		||||
 | 
			
		||||
        std::string result;
 | 
			
		||||
        result += '(';
 | 
			
		||||
 | 
			
		||||
        for (size_t i = 0; i < shift_amounts.size(); ++i) {
 | 
			
		||||
            if (i)
 | 
			
		||||
                result += '|';
 | 
			
		||||
            result += "(((" + imm_lut + " >> (((" + op_c + " >> " + shift_amounts[i] +
 | 
			
		||||
                      ") & 1) | ((" + op_b + " >> " + shift_amounts[i] + ") & 1) << 1 | ((" + op_a +
 | 
			
		||||
                      " >> " + shift_amounts[i] + ") & 1) << 2)) & 1) << " + shift_amounts[i] + ")";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        result += ')';
 | 
			
		||||
 | 
			
		||||
        regs.SetRegisterToInteger(dest, true, 0, result, 1, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void WriteTexsInstruction(const Instruction& instr, const std::string& coord,
 | 
			
		||||
                              const std::string& texture) {
 | 
			
		||||
        // Add an extra scope and declare the texture coords inside to prevent
 | 
			
		||||
@ -1297,6 +1324,20 @@ private:
 | 
			
		||||
                                    instr.alu.lop.pred_result_mode, instr.alu.lop.pred48);
 | 
			
		||||
                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_R:
 | 
			
		||||
            case OpCode::Id::IMNMX_IMM: {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user