mirror of
				https://git.zaroz.cloud/nintendo-back-up/yuzu/yuzu.git
				synced 2025-05-12 00:45:25 +00:00 
			
		
		
		
	gl_shader_decompiler: Implement FMUL/FADD/FFMA immediate instructions.
This commit is contained in:
		
							parent
							
								
									8d4899d6ea
								
							
						
					
					
						commit
						5a28dce9eb
					
				| @ -4,6 +4,7 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <cstring> | ||||||
| #include <map> | #include <map> | ||||||
| #include <string> | #include <string> | ||||||
| #include "common/bit_field.h" | #include "common/bit_field.h" | ||||||
| @ -289,6 +290,7 @@ enum class SubOp : u64 { | |||||||
|     Lg2 = 0x3, |     Lg2 = 0x3, | ||||||
|     Rcp = 0x4, |     Rcp = 0x4, | ||||||
|     Rsq = 0x5, |     Rsq = 0x5, | ||||||
|  |     Min = 0x8, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| union Instruction { | union Instruction { | ||||||
| @ -307,11 +309,22 @@ union Instruction { | |||||||
|     BitField<39, 8, Register> gpr39; |     BitField<39, 8, Register> gpr39; | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
|  |         BitField<20, 19, u64> imm20; | ||||||
|         BitField<45, 1, u64> negate_b; |         BitField<45, 1, u64> negate_b; | ||||||
|         BitField<46, 1, u64> abs_a; |         BitField<46, 1, u64> abs_a; | ||||||
|         BitField<48, 1, u64> negate_a; |         BitField<48, 1, u64> negate_a; | ||||||
|         BitField<49, 1, u64> abs_b; |         BitField<49, 1, u64> abs_b; | ||||||
|         BitField<50, 1, u64> abs_d; |         BitField<50, 1, u64> abs_d; | ||||||
|  |         BitField<56, 1, u64> negate_imm; | ||||||
|  | 
 | ||||||
|  |         float GetImm20() const { | ||||||
|  |             float result{}; | ||||||
|  |             u32 imm{static_cast<u32>(imm20)}; | ||||||
|  |             imm <<= 12; | ||||||
|  |             imm |= negate_imm ? 0x80000000 : 0; | ||||||
|  |             std::memcpy(&result, &imm, sizeof(imm)); | ||||||
|  |             return result; | ||||||
|  |         } | ||||||
|     } alu; |     } alu; | ||||||
| 
 | 
 | ||||||
|     union { |     union { | ||||||
| @ -319,6 +332,7 @@ union Instruction { | |||||||
|         BitField<49, 1, u64> negate_c; |         BitField<49, 1, u64> negate_c; | ||||||
|     } ffma; |     } ffma; | ||||||
| 
 | 
 | ||||||
|  |     BitField<61, 1, u64> is_b_imm; | ||||||
|     BitField<60, 1, u64> is_b_gpr; |     BitField<60, 1, u64> is_b_gpr; | ||||||
|     BitField<59, 1, u64> is_c_gpr; |     BitField<59, 1, u64> is_c_gpr; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -190,6 +190,11 @@ private: | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /// Generates code representing an immediate value
 | ||||||
|  |     static std::string GetImmediate(const Instruction& instr) { | ||||||
|  |         return std::to_string(instr.alu.GetImm20()); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     /// Generates code representing a temporary (GPR) register.
 |     /// Generates code representing a temporary (GPR) register.
 | ||||||
|     std::string GetRegister(const Register& reg, unsigned elem = 0) { |     std::string GetRegister(const Register& reg, unsigned elem = 0) { | ||||||
|         if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) { |         if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) { | ||||||
| @ -269,24 +274,32 @@ private: | |||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             std::string op_b = instr.alu.negate_b ? "-" : ""; |             std::string op_b = instr.alu.negate_b ? "-" : ""; | ||||||
|  | 
 | ||||||
|  |             if (instr.is_b_imm) { | ||||||
|  |                 op_b += GetImmediate(instr); | ||||||
|  |             } else { | ||||||
|                 if (instr.is_b_gpr) { |                 if (instr.is_b_gpr) { | ||||||
|                     op_b += GetRegister(instr.gpr20); |                     op_b += GetRegister(instr.gpr20); | ||||||
|                 } else { |                 } else { | ||||||
|                     op_b += GetUniform(instr.uniform); |                     op_b += GetUniform(instr.uniform); | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|             if (instr.alu.abs_b) { |             if (instr.alu.abs_b) { | ||||||
|                 op_b = "abs(" + op_b + ")"; |                 op_b = "abs(" + op_b + ")"; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             switch (instr.opcode.EffectiveOpCode()) { |             switch (instr.opcode.EffectiveOpCode()) { | ||||||
|             case OpCode::Id::FMUL_C: |             case OpCode::Id::FMUL_C: | ||||||
|             case OpCode::Id::FMUL_R: { |             case OpCode::Id::FMUL_R: | ||||||
|                 SetDest(0, dest, op_a + " * " + op_b, 1, 1); |             case OpCode::Id::FMUL_IMM: { | ||||||
|  |                 SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case OpCode::Id::FADD_C: |             case OpCode::Id::FADD_C: | ||||||
|             case OpCode::Id::FADD_R: { |             case OpCode::Id::FADD_R: | ||||||
|                 SetDest(0, dest, op_a + " + " + op_b, 1, 1); |             case OpCode::Id::FADD_IMM: { | ||||||
|  |                 SetDest(0, dest, op_a + " + " + op_b, 1, 1, instr.alu.abs_d); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             case OpCode::Id::MUFU: { |             case OpCode::Id::MUFU: { | ||||||
| @ -316,16 +329,28 @@ private: | |||||||
| 
 | 
 | ||||||
|             std::string dest = GetRegister(instr.gpr0); |             std::string dest = GetRegister(instr.gpr0); | ||||||
|             std::string op_a = GetRegister(instr.gpr8); |             std::string op_a = GetRegister(instr.gpr8); | ||||||
| 
 |  | ||||||
|             std::string op_b = instr.ffma.negate_b ? "-" : ""; |             std::string op_b = instr.ffma.negate_b ? "-" : ""; | ||||||
|             op_b += GetUniform(instr.uniform); |  | ||||||
| 
 |  | ||||||
|             std::string op_c = instr.ffma.negate_c ? "-" : ""; |             std::string op_c = instr.ffma.negate_c ? "-" : ""; | ||||||
|             op_c += GetRegister(instr.gpr39); |  | ||||||
| 
 | 
 | ||||||
|             switch (instr.opcode.EffectiveOpCode()) { |             switch (instr.opcode.EffectiveOpCode()) { | ||||||
|             case OpCode::Id::FFMA_CR: { |             case OpCode::Id::FFMA_CR: { | ||||||
|                 SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1); |                 op_b += GetUniform(instr.uniform); | ||||||
|  |                 op_c += GetRegister(instr.gpr39); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case OpCode::Id::FFMA_RR: { | ||||||
|  |                 op_b += GetRegister(instr.gpr20); | ||||||
|  |                 op_c += GetRegister(instr.gpr39); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case OpCode::Id::FFMA_RC: { | ||||||
|  |                 op_b += GetRegister(instr.gpr39); | ||||||
|  |                 op_c += GetUniform(instr.uniform); | ||||||
|  |                 break; | ||||||
|  |             } | ||||||
|  |             case OpCode::Id::FFMA_IMM: { | ||||||
|  |                 op_b += GetImmediate(instr); | ||||||
|  |                 op_c += GetRegister(instr.gpr39); | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             default: { |             default: { | ||||||
| @ -336,6 +361,8 @@ private: | |||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|         case OpCode::Type::Memory: { |         case OpCode::Type::Memory: { | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 bunnei
						bunnei