forked from eden-emu/eden
		
	shader: Implement DMUL and DFMA
Also add a missing const on DADD
This commit is contained in:
		
							parent
							
								
									112b8f00f0
								
							
						
					
					
						commit
						c858b8ba97
					
				
					 8 changed files with 111 additions and 30 deletions
				
			
		|  | @ -65,6 +65,8 @@ add_library(shader_recompiler STATIC | |||
|     frontend/maxwell/translate/impl/common_funcs.h | ||||
|     frontend/maxwell/translate/impl/condition_code_set.cpp | ||||
|     frontend/maxwell/translate/impl/double_add.cpp | ||||
|     frontend/maxwell/translate/impl/double_fused_multiply_add.cpp | ||||
|     frontend/maxwell/translate/impl/double_multiply.cpp | ||||
|     frontend/maxwell/translate/impl/exit_program.cpp | ||||
|     frontend/maxwell/translate/impl/find_leading_one.cpp | ||||
|     frontend/maxwell/translate/impl/floating_point_add.cpp | ||||
|  |  | |||
|  | @ -35,7 +35,7 @@ INST(DADD_imm,     "DADD (imm)",     "0011 100- 0111 0---") | |||
| INST(DEPBAR,       "DEPBAR",         "1111 0000 1111 0---") | ||||
| INST(DFMA_reg,     "DFMA (reg)",     "0101 1011 0111 ----") | ||||
| INST(DFMA_rc,      "DFMA (rc)",      "0101 0011 0111 ----") | ||||
| INST(DFMA_cr,      "DFMA (cr)",      "0010 1011 0111 ----") | ||||
| INST(DFMA_cr,      "DFMA (cr)",      "0100 1011 0111 ----") | ||||
| INST(DFMA_imm,     "DFMA (imm)",     "0011 011- 0111 ----") | ||||
| INST(DMNMX_reg,    "DMNMX (reg)",    "0100 1100 0101 0---") | ||||
| INST(DMNMX_cbuf,   "DMNMX (cbuf)",   "0101 1100 0101 0---") | ||||
|  |  | |||
|  | @ -30,7 +30,7 @@ void DADD(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) { | |||
|     const IR::F64 op_a{v.ir.FPAbsNeg(src_a, dadd.abs_a != 0, dadd.neg_a != 0)}; | ||||
|     const IR::F64 op_b{v.ir.FPAbsNeg(src_b, dadd.abs_b != 0, dadd.neg_b != 0)}; | ||||
| 
 | ||||
|     IR::FpControl control{ | ||||
|     const IR::FpControl control{ | ||||
|         .no_contraction{true}, | ||||
|         .rounding{CastFpRounding(dadd.fp_rounding)}, | ||||
|         .fmz_mode{IR::FmzMode::None}, | ||||
|  |  | |||
|  | @ -0,0 +1,53 @@ | |||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| 
 | ||||
| void DFMA(TranslatorVisitor& v, u64 insn, const IR::F64& src_b, const IR::F64& src_c) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<0, 8, IR::Reg> dest_reg; | ||||
|         BitField<8, 8, IR::Reg> src_a_reg; | ||||
|         BitField<50, 2, FpRounding> fp_rounding; | ||||
|         BitField<48, 1, u64> neg_b; | ||||
|         BitField<49, 1, u64> neg_c; | ||||
|     } const dfma{insn}; | ||||
| 
 | ||||
|     const IR::F64 src_a{v.D(dfma.src_a_reg)}; | ||||
|     const IR::F64 op_b{v.ir.FPAbsNeg(src_b, false, dfma.neg_b != 0)}; | ||||
|     const IR::F64 op_c{v.ir.FPAbsNeg(src_c, false, dfma.neg_c != 0)}; | ||||
| 
 | ||||
|     const IR::FpControl control{ | ||||
|         .no_contraction{true}, | ||||
|         .rounding{CastFpRounding(dfma.fp_rounding)}, | ||||
|         .fmz_mode{IR::FmzMode::None}, | ||||
|     }; | ||||
| 
 | ||||
|     v.D(dfma.dest_reg, v.ir.FPFma(src_a, op_b, op_c, control)); | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_reg(u64 insn) { | ||||
|     DFMA(*this, insn, GetDoubleReg20(insn), GetDoubleReg39(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_cr(u64 insn) { | ||||
|     DFMA(*this, insn, GetDoubleCbuf(insn), GetDoubleReg39(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_rc(u64 insn) { | ||||
|     DFMA(*this, insn, GetDoubleReg39(insn), GetDoubleCbuf(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_imm(u64 insn) { | ||||
|     DFMA(*this, insn, GetDoubleImm20(insn), GetDoubleReg39(insn)); | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  | @ -0,0 +1,45 @@ | |||
| // Copyright 2021 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include "common/common_types.h" | ||||
| #include "shader_recompiler/exception.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/common_encoding.h" | ||||
| #include "shader_recompiler/frontend/maxwell/translate/impl/impl.h" | ||||
| 
 | ||||
| namespace Shader::Maxwell { | ||||
| namespace { | ||||
| 
 | ||||
| void DMUL(TranslatorVisitor& v, u64 insn, const IR::F64& src_b) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<0, 8, IR::Reg> dest_reg; | ||||
|         BitField<8, 8, IR::Reg> src_a_reg; | ||||
|         BitField<39, 2, FpRounding> fp_rounding; | ||||
|         BitField<48, 1, u64> neg; | ||||
|     } const dmul{insn}; | ||||
| 
 | ||||
|     const IR::F64 src_a{v.ir.FPAbsNeg(v.D(dmul.src_a_reg), false, dmul.neg != 0)}; | ||||
|     const IR::FpControl control{ | ||||
|         .no_contraction{true}, | ||||
|         .rounding{CastFpRounding(dmul.fp_rounding)}, | ||||
|         .fmz_mode{IR::FmzMode::None}, | ||||
|     }; | ||||
| 
 | ||||
|     v.D(dmul.dest_reg, v.ir.FPMul(src_a, src_b, control)); | ||||
| } | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_reg(u64 insn) { | ||||
|     DMUL(*this, insn, GetDoubleReg20(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_cbuf(u64 insn) { | ||||
|     DMUL(*this, insn, GetDoubleCbuf(insn)); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_imm(u64 insn) { | ||||
|     DMUL(*this, insn, GetDoubleImm20(insn)); | ||||
| } | ||||
| 
 | ||||
| } // namespace Shader::Maxwell
 | ||||
|  | @ -90,6 +90,14 @@ IR::F64 TranslatorVisitor::GetDoubleReg20(u64 insn) { | |||
|     return D(reg.index); | ||||
| } | ||||
| 
 | ||||
| IR::F64 TranslatorVisitor::GetDoubleReg39(u64 insn) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<39, 8, IR::Reg> index; | ||||
|     } const reg{insn}; | ||||
|     return D(reg.index); | ||||
| } | ||||
| 
 | ||||
| static std::pair<IR::U32, IR::U32> CbufAddr(u64 insn) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|  |  | |||
|  | @ -354,6 +354,7 @@ public: | |||
|     [[nodiscard]] IR::F32 GetFloatReg20(u64 insn); | ||||
|     [[nodiscard]] IR::F32 GetFloatReg39(u64 insn); | ||||
|     [[nodiscard]] IR::F64 GetDoubleReg20(u64 insn); | ||||
|     [[nodiscard]] IR::F64 GetDoubleReg39(u64 insn); | ||||
| 
 | ||||
|     [[nodiscard]] IR::U32 GetCbuf(u64 insn); | ||||
|     [[nodiscard]] IR::F32 GetFloatCbuf(u64 insn); | ||||
|  |  | |||
|  | @ -81,22 +81,6 @@ void TranslatorVisitor::DEPBAR() { | |||
|     // DEPBAR is a no-op
 | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::DFMA_reg); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_rc(u64) { | ||||
|     ThrowNotImplemented(Opcode::DFMA_rc); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_cr(u64) { | ||||
|     ThrowNotImplemented(Opcode::DFMA_cr); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DFMA_imm(u64) { | ||||
|     ThrowNotImplemented(Opcode::DFMA_imm); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMNMX_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::DMNMX_reg); | ||||
| } | ||||
|  | @ -109,18 +93,6 @@ void TranslatorVisitor::DMNMX_imm(u64) { | |||
|     ThrowNotImplemented(Opcode::DMNMX_imm); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::DMUL_reg); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_cbuf(u64) { | ||||
|     ThrowNotImplemented(Opcode::DMUL_cbuf); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DMUL_imm(u64) { | ||||
|     ThrowNotImplemented(Opcode::DMUL_imm); | ||||
| } | ||||
| 
 | ||||
| void TranslatorVisitor::DSET_reg(u64) { | ||||
|     ThrowNotImplemented(Opcode::DSET_reg); | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ameerj
						ameerj