gl_shader_decompiler: Implement non-immediate HADD2 and HMUL2 instructions
This commit is contained in:
		
							parent
							
								
									08d751d882
								
							
						
					
					
						commit
						d46e2a6e7a
					
				@ -573,6 +573,22 @@ union Instruction {
 | 
			
		||||
        BitField<49, 1, u64> negate_a;
 | 
			
		||||
    } alu_integer;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<39, 1, u64> ftz;
 | 
			
		||||
        BitField<32, 1, u64> saturate;
 | 
			
		||||
        BitField<49, 2, HalfMerge> merge;
 | 
			
		||||
 | 
			
		||||
        BitField<43, 1, u64> negate_a;
 | 
			
		||||
        BitField<44, 1, u64> abs_a;
 | 
			
		||||
        BitField<47, 2, HalfType> type_a;
 | 
			
		||||
 | 
			
		||||
        BitField<31, 1, u64> negate_b;
 | 
			
		||||
        BitField<30, 1, u64> abs_b;
 | 
			
		||||
        BitField<47, 2, HalfType> type_b;
 | 
			
		||||
 | 
			
		||||
        BitField<35, 2, HalfType> type_c;
 | 
			
		||||
    } alu_half;
 | 
			
		||||
 | 
			
		||||
    union {
 | 
			
		||||
        BitField<40, 1, u64> invert;
 | 
			
		||||
    } popc;
 | 
			
		||||
@ -1165,6 +1181,10 @@ public:
 | 
			
		||||
        LEA_RZ,
 | 
			
		||||
        LEA_IMM,
 | 
			
		||||
        LEA_HI,
 | 
			
		||||
        HADD2_C,
 | 
			
		||||
        HADD2_R,
 | 
			
		||||
        HMUL2_C,
 | 
			
		||||
        HMUL2_R,
 | 
			
		||||
        POPC_C,
 | 
			
		||||
        POPC_R,
 | 
			
		||||
        POPC_IMM,
 | 
			
		||||
@ -1238,6 +1258,7 @@ public:
 | 
			
		||||
        ArithmeticImmediate,
 | 
			
		||||
        ArithmeticInteger,
 | 
			
		||||
        ArithmeticIntegerImmediate,
 | 
			
		||||
        ArithmeticHalf,
 | 
			
		||||
        Bfe,
 | 
			
		||||
        Shift,
 | 
			
		||||
        Ffma,
 | 
			
		||||
@ -1409,6 +1430,10 @@ private:
 | 
			
		||||
            INST("001101101101----", Id::LEA_IMM, Type::ArithmeticInteger, "LEA_IMM"),
 | 
			
		||||
            INST("010010111101----", Id::LEA_RZ, Type::ArithmeticInteger, "LEA_RZ"),
 | 
			
		||||
            INST("00011000--------", Id::LEA_HI, Type::ArithmeticInteger, "LEA_HI"),
 | 
			
		||||
            INST("0111101-1-------", Id::HADD2_C, Type::ArithmeticHalf, "HADD2_C"),
 | 
			
		||||
            INST("0101110100010---", Id::HADD2_R, Type::ArithmeticHalf, "HADD2_R"),
 | 
			
		||||
            INST("0111100-1-------", Id::HMUL2_C, Type::ArithmeticHalf, "HMUL2_C"),
 | 
			
		||||
            INST("0101110100001---", Id::HMUL2_R, Type::ArithmeticHalf, "HMUL2_R"),
 | 
			
		||||
            INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
 | 
			
		||||
            INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
 | 
			
		||||
            INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
 | 
			
		||||
 | 
			
		||||
@ -1827,6 +1827,56 @@ private:
 | 
			
		||||
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case OpCode::Type::ArithmeticHalf: {
 | 
			
		||||
            if (opcode->GetId() == OpCode::Id::HADD2_C || opcode->GetId() == OpCode::Id::HADD2_R) {
 | 
			
		||||
                ASSERT_MSG(instr.alu_half.ftz == 0, "Unimplemented");
 | 
			
		||||
            }
 | 
			
		||||
            const bool negate_a =
 | 
			
		||||
                opcode->GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
 | 
			
		||||
            const bool negate_b =
 | 
			
		||||
                opcode->GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
 | 
			
		||||
 | 
			
		||||
            const std::string op_a =
 | 
			
		||||
                GetHalfFloat(regs.GetRegisterAsInteger(instr.gpr8, 0, false), instr.alu_half.type_a,
 | 
			
		||||
                             instr.alu_half.abs_a != 0, negate_a);
 | 
			
		||||
 | 
			
		||||
            std::string op_b;
 | 
			
		||||
            switch (opcode->GetId()) {
 | 
			
		||||
            case OpCode::Id::HADD2_C:
 | 
			
		||||
            case OpCode::Id::HMUL2_C:
 | 
			
		||||
                op_b = regs.GetUniform(instr.cbuf34.index, instr.cbuf34.offset,
 | 
			
		||||
                                       GLSLRegister::Type::UnsignedInteger);
 | 
			
		||||
                break;
 | 
			
		||||
            case OpCode::Id::HADD2_R:
 | 
			
		||||
            case OpCode::Id::HMUL2_R:
 | 
			
		||||
                op_b = regs.GetRegisterAsInteger(instr.gpr20, 0, false);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                UNREACHABLE();
 | 
			
		||||
                op_b = "0";
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            op_b = GetHalfFloat(op_b, instr.alu_half.type_b, instr.alu_half.abs_b != 0, negate_b);
 | 
			
		||||
 | 
			
		||||
            const std::string result = [&]() {
 | 
			
		||||
                switch (opcode->GetId()) {
 | 
			
		||||
                case OpCode::Id::HADD2_C:
 | 
			
		||||
                case OpCode::Id::HADD2_R:
 | 
			
		||||
                    return '(' + op_a + " + " + op_b + ')';
 | 
			
		||||
                case OpCode::Id::HMUL2_C:
 | 
			
		||||
                case OpCode::Id::HMUL2_R:
 | 
			
		||||
                    return '(' + op_a + " * " + op_b + ')';
 | 
			
		||||
                default:
 | 
			
		||||
                    LOG_CRITICAL(HW_GPU, "Unhandled half float instruction: {}", opcode->GetName());
 | 
			
		||||
                    UNREACHABLE();
 | 
			
		||||
                    return std::string("0");
 | 
			
		||||
                }
 | 
			
		||||
            }();
 | 
			
		||||
 | 
			
		||||
            regs.SetRegisterToHalfFloat(instr.gpr0, 0, result, instr.alu_half.merge, 1, 1,
 | 
			
		||||
                                        instr.alu_half.saturate != 0);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        case OpCode::Type::Ffma: {
 | 
			
		||||
            const std::string op_a = regs.GetRegisterAsFloat(instr.gpr8);
 | 
			
		||||
            std::string op_b = instr.ffma.negate_b ? "-" : "";
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user