mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	Merge pull request #1289 from FernandoS27/lea_pset
shader_decompiler: Implemented LEA and PSET
This commit is contained in:
		
						commit
						429217248f
					
				@ -423,6 +423,45 @@ union Instruction {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    } bfe;
 | 
					    } bfe;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        BitField<48, 3, u64> pred48;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<20, 20, u64> entry_a;
 | 
				
			||||||
 | 
					            BitField<39, 5, u64> entry_b;
 | 
				
			||||||
 | 
					            BitField<45, 1, u64> neg;
 | 
				
			||||||
 | 
					            BitField<46, 1, u64> uses_cc;
 | 
				
			||||||
 | 
					        } imm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<20, 14, u64> cb_index;
 | 
				
			||||||
 | 
					            BitField<34, 5, u64> cb_offset;
 | 
				
			||||||
 | 
					            BitField<56, 1, u64> neg;
 | 
				
			||||||
 | 
					            BitField<57, 1, u64> uses_cc;
 | 
				
			||||||
 | 
					        } hi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<20, 14, u64> cb_index;
 | 
				
			||||||
 | 
					            BitField<34, 5, u64> cb_offset;
 | 
				
			||||||
 | 
					            BitField<39, 5, u64> entry_a;
 | 
				
			||||||
 | 
					            BitField<45, 1, u64> neg;
 | 
				
			||||||
 | 
					            BitField<46, 1, u64> uses_cc;
 | 
				
			||||||
 | 
					        } rz;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<39, 5, u64> entry_a;
 | 
				
			||||||
 | 
					            BitField<45, 1, u64> neg;
 | 
				
			||||||
 | 
					            BitField<46, 1, u64> uses_cc;
 | 
				
			||||||
 | 
					        } r1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        union {
 | 
				
			||||||
 | 
					            BitField<28, 8, u64> entry_a;
 | 
				
			||||||
 | 
					            BitField<37, 1, u64> neg;
 | 
				
			||||||
 | 
					            BitField<38, 1, u64> uses_cc;
 | 
				
			||||||
 | 
					        } r2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    } lea;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    union {
 | 
					    union {
 | 
				
			||||||
        BitField<0, 5, FlowCondition> cond;
 | 
					        BitField<0, 5, FlowCondition> cond;
 | 
				
			||||||
    } flow;
 | 
					    } flow;
 | 
				
			||||||
@ -477,6 +516,18 @@ union Instruction {
 | 
				
			|||||||
        BitField<45, 2, PredOperation> op;
 | 
					        BitField<45, 2, PredOperation> op;
 | 
				
			||||||
    } psetp;
 | 
					    } psetp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        BitField<12, 3, u64> pred12;
 | 
				
			||||||
 | 
					        BitField<15, 1, u64> neg_pred12;
 | 
				
			||||||
 | 
					        BitField<24, 2, PredOperation> cond;
 | 
				
			||||||
 | 
					        BitField<29, 3, u64> pred29;
 | 
				
			||||||
 | 
					        BitField<32, 1, u64> neg_pred29;
 | 
				
			||||||
 | 
					        BitField<39, 3, u64> pred39;
 | 
				
			||||||
 | 
					        BitField<42, 1, u64> neg_pred39;
 | 
				
			||||||
 | 
					        BitField<44, 1, u64> bf;
 | 
				
			||||||
 | 
					        BitField<45, 2, PredOperation> op;
 | 
				
			||||||
 | 
					    } pset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    union {
 | 
					    union {
 | 
				
			||||||
        BitField<39, 3, u64> pred39;
 | 
					        BitField<39, 3, u64> pred39;
 | 
				
			||||||
        BitField<42, 1, u64> neg_pred;
 | 
					        BitField<42, 1, u64> neg_pred;
 | 
				
			||||||
@ -726,6 +777,11 @@ public:
 | 
				
			|||||||
        ISCADD_C, // Scale and Add
 | 
					        ISCADD_C, // Scale and Add
 | 
				
			||||||
        ISCADD_R,
 | 
					        ISCADD_R,
 | 
				
			||||||
        ISCADD_IMM,
 | 
					        ISCADD_IMM,
 | 
				
			||||||
 | 
					        LEA_R1,
 | 
				
			||||||
 | 
					        LEA_R2,
 | 
				
			||||||
 | 
					        LEA_RZ,
 | 
				
			||||||
 | 
					        LEA_IMM,
 | 
				
			||||||
 | 
					        LEA_HI,
 | 
				
			||||||
        POPC_C,
 | 
					        POPC_C,
 | 
				
			||||||
        POPC_R,
 | 
					        POPC_R,
 | 
				
			||||||
        POPC_IMM,
 | 
					        POPC_IMM,
 | 
				
			||||||
@ -784,6 +840,7 @@ public:
 | 
				
			|||||||
        ISET_C,
 | 
					        ISET_C,
 | 
				
			||||||
        ISET_IMM,
 | 
					        ISET_IMM,
 | 
				
			||||||
        PSETP,
 | 
					        PSETP,
 | 
				
			||||||
 | 
					        PSET,
 | 
				
			||||||
        XMAD_IMM,
 | 
					        XMAD_IMM,
 | 
				
			||||||
        XMAD_CR,
 | 
					        XMAD_CR,
 | 
				
			||||||
        XMAD_RC,
 | 
					        XMAD_RC,
 | 
				
			||||||
@ -807,6 +864,7 @@ public:
 | 
				
			|||||||
        IntegerSet,
 | 
					        IntegerSet,
 | 
				
			||||||
        IntegerSetPredicate,
 | 
					        IntegerSetPredicate,
 | 
				
			||||||
        PredicateSetPredicate,
 | 
					        PredicateSetPredicate,
 | 
				
			||||||
 | 
					        PredicateSetRegister,
 | 
				
			||||||
        Conversion,
 | 
					        Conversion,
 | 
				
			||||||
        Xmad,
 | 
					        Xmad,
 | 
				
			||||||
        Unknown,
 | 
					        Unknown,
 | 
				
			||||||
@ -958,6 +1016,11 @@ private:
 | 
				
			|||||||
            INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
 | 
					            INST("0100110010100---", Id::SEL_C, Type::ArithmeticInteger, "SEL_C"),
 | 
				
			||||||
            INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
 | 
					            INST("0101110010100---", Id::SEL_R, Type::ArithmeticInteger, "SEL_R"),
 | 
				
			||||||
            INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),
 | 
					            INST("0011100-10100---", Id::SEL_IMM, Type::ArithmeticInteger, "SEL_IMM"),
 | 
				
			||||||
 | 
					            INST("0101101111011---", Id::LEA_R2, Type::ArithmeticInteger, "LEA_R2"),
 | 
				
			||||||
 | 
					            INST("0101101111010---", Id::LEA_R1, Type::ArithmeticInteger, "LEA_R1"),
 | 
				
			||||||
 | 
					            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("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
 | 
					            INST("0101000010000---", Id::MUFU, Type::Arithmetic, "MUFU"),
 | 
				
			||||||
            INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
 | 
					            INST("0100110010010---", Id::RRO_C, Type::Arithmetic, "RRO_C"),
 | 
				
			||||||
            INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
 | 
					            INST("0101110010010---", Id::RRO_R, Type::Arithmetic, "RRO_R"),
 | 
				
			||||||
@ -1012,6 +1075,7 @@ private:
 | 
				
			|||||||
            INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"),
 | 
					            INST("010110110101----", Id::ISET_R, Type::IntegerSet, "ISET_R"),
 | 
				
			||||||
            INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"),
 | 
					            INST("010010110101----", Id::ISET_C, Type::IntegerSet, "ISET_C"),
 | 
				
			||||||
            INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
 | 
					            INST("0011011-0101----", Id::ISET_IMM, Type::IntegerSet, "ISET_IMM"),
 | 
				
			||||||
 | 
					            INST("0101000010001---", Id::PSET, Type::PredicateSetRegister, "PSET"),
 | 
				
			||||||
            INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
 | 
					            INST("0101000010010---", Id::PSETP, Type::PredicateSetPredicate, "PSETP"),
 | 
				
			||||||
            INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
 | 
					            INST("0011011-00------", Id::XMAD_IMM, Type::Xmad, "XMAD_IMM"),
 | 
				
			||||||
            INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
 | 
					            INST("0100111---------", Id::XMAD_CR, Type::Xmad, "XMAD_CR"),
 | 
				
			||||||
 | 
				
			|||||||
@ -1505,6 +1505,73 @@ private:
 | 
				
			|||||||
                                          1, 1);
 | 
					                                          1, 1);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            case OpCode::Id::LEA_R2:
 | 
				
			||||||
 | 
					            case OpCode::Id::LEA_R1:
 | 
				
			||||||
 | 
					            case OpCode::Id::LEA_IMM:
 | 
				
			||||||
 | 
					            case OpCode::Id::LEA_RZ:
 | 
				
			||||||
 | 
					            case OpCode::Id::LEA_HI: {
 | 
				
			||||||
 | 
					                std::string op_a;
 | 
				
			||||||
 | 
					                std::string op_b;
 | 
				
			||||||
 | 
					                std::string op_c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                switch (opcode->GetId()) {
 | 
				
			||||||
 | 
					                case OpCode::Id::LEA_R2: {
 | 
				
			||||||
 | 
					                    op_a = regs.GetRegisterAsInteger(instr.gpr20);
 | 
				
			||||||
 | 
					                    op_b = regs.GetRegisterAsInteger(instr.gpr39);
 | 
				
			||||||
 | 
					                    op_c = std::to_string(instr.lea.r2.entry_a);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case OpCode::Id::LEA_R1: {
 | 
				
			||||||
 | 
					                    const bool neg = instr.lea.r1.neg != 0;
 | 
				
			||||||
 | 
					                    op_a = regs.GetRegisterAsInteger(instr.gpr8);
 | 
				
			||||||
 | 
					                    if (neg)
 | 
				
			||||||
 | 
					                        op_a = "-(" + op_a + ')';
 | 
				
			||||||
 | 
					                    op_b = regs.GetRegisterAsInteger(instr.gpr20);
 | 
				
			||||||
 | 
					                    op_c = std::to_string(instr.lea.r1.entry_a);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case OpCode::Id::LEA_IMM: {
 | 
				
			||||||
 | 
					                    const bool neg = instr.lea.imm.neg != 0;
 | 
				
			||||||
 | 
					                    op_b = regs.GetRegisterAsInteger(instr.gpr8);
 | 
				
			||||||
 | 
					                    if (neg)
 | 
				
			||||||
 | 
					                        op_b = "-(" + op_b + ')';
 | 
				
			||||||
 | 
					                    op_a = std::to_string(instr.lea.imm.entry_a);
 | 
				
			||||||
 | 
					                    op_c = std::to_string(instr.lea.imm.entry_b);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case OpCode::Id::LEA_RZ: {
 | 
				
			||||||
 | 
					                    const bool neg = instr.lea.rz.neg != 0;
 | 
				
			||||||
 | 
					                    op_b = regs.GetRegisterAsInteger(instr.gpr8);
 | 
				
			||||||
 | 
					                    if (neg)
 | 
				
			||||||
 | 
					                        op_b = "-(" + op_b + ')';
 | 
				
			||||||
 | 
					                    op_a = regs.GetUniform(instr.lea.rz.cb_index, instr.lea.rz.cb_offset,
 | 
				
			||||||
 | 
					                                           GLSLRegister::Type::Integer);
 | 
				
			||||||
 | 
					                    op_c = std::to_string(instr.lea.rz.entry_a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                case OpCode::Id::LEA_HI:
 | 
				
			||||||
 | 
					                default: {
 | 
				
			||||||
 | 
					                    op_b = regs.GetRegisterAsInteger(instr.gpr8);
 | 
				
			||||||
 | 
					                    op_a = std::to_string(instr.lea.imm.entry_a);
 | 
				
			||||||
 | 
					                    op_c = std::to_string(instr.lea.imm.entry_b);
 | 
				
			||||||
 | 
					                    LOG_CRITICAL(HW_GPU, "Unhandled LEA subinstruction: {}", opcode->GetName());
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                if (instr.lea.pred48 != static_cast<u64>(Pred::UnusedIndex)) {
 | 
				
			||||||
 | 
					                    LOG_ERROR(HW_GPU, "Unhandled LEA Predicate");
 | 
				
			||||||
 | 
					                    UNREACHABLE();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                const std::string value = '(' + op_a + " + (" + op_b + "*(1 << " + op_c + ")))";
 | 
				
			||||||
 | 
					                regs.SetRegisterToInteger(instr.gpr0, true, 0, value, 1, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            default: {
 | 
					            default: {
 | 
				
			||||||
                LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}",
 | 
					                LOG_CRITICAL(HW_GPU, "Unhandled ArithmeticInteger instruction: {}",
 | 
				
			||||||
                             opcode->GetName());
 | 
					                             opcode->GetName());
 | 
				
			||||||
@ -2087,6 +2154,30 @@ private:
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        case OpCode::Type::PredicateSetRegister: {
 | 
				
			||||||
 | 
					            const std::string op_a =
 | 
				
			||||||
 | 
					                GetPredicateCondition(instr.pset.pred12, instr.pset.neg_pred12 != 0);
 | 
				
			||||||
 | 
					            const std::string op_b =
 | 
				
			||||||
 | 
					                GetPredicateCondition(instr.pset.pred29, instr.pset.neg_pred29 != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const std::string second_pred =
 | 
				
			||||||
 | 
					                GetPredicateCondition(instr.pset.pred39, instr.pset.neg_pred39 != 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const std::string combiner = GetPredicateCombiner(instr.pset.op);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const std::string predicate =
 | 
				
			||||||
 | 
					                '(' + op_a + ") " + GetPredicateCombiner(instr.pset.cond) + " (" + op_b + ')';
 | 
				
			||||||
 | 
					            const std::string result = '(' + predicate + ") " + combiner + " (" + second_pred + ')';
 | 
				
			||||||
 | 
					            if (instr.pset.bf == 0) {
 | 
				
			||||||
 | 
					                const std::string value = '(' + result + ") ? 0xFFFFFFFF : 0";
 | 
				
			||||||
 | 
					                regs.SetRegisterToInteger(instr.gpr0, false, 0, value, 1, 1);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                const std::string value = '(' + result + ") ? 1.0 : 0.0";
 | 
				
			||||||
 | 
					                regs.SetRegisterToFloat(instr.gpr0, 0, value, 1, 1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        case OpCode::Type::PredicateSetPredicate: {
 | 
					        case OpCode::Type::PredicateSetPredicate: {
 | 
				
			||||||
            const std::string op_a =
 | 
					            const std::string op_a =
 | 
				
			||||||
                GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
 | 
					                GetPredicateCondition(instr.psetp.pred12, instr.psetp.neg_pred12 != 0);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user