gl_shader_decompiler: Implement FMUL/FADD/FFMA immediate instructions.

This commit is contained in:
bunnei 2018-04-15 20:45:56 -04:00
parent 8d4899d6ea
commit 5a28dce9eb
2 changed files with 53 additions and 12 deletions

View file

@ -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.
std::string GetRegister(const Register& reg, unsigned elem = 0) {
if (stage == Maxwell3D::Regs::ShaderStage::Fragment && reg < 4) {
@ -269,24 +274,32 @@ private:
}
std::string op_b = instr.alu.negate_b ? "-" : "";
if (instr.is_b_gpr) {
op_b += GetRegister(instr.gpr20);
if (instr.is_b_imm) {
op_b += GetImmediate(instr);
} else {
op_b += GetUniform(instr.uniform);
if (instr.is_b_gpr) {
op_b += GetRegister(instr.gpr20);
} else {
op_b += GetUniform(instr.uniform);
}
}
if (instr.alu.abs_b) {
op_b = "abs(" + op_b + ")";
}
switch (instr.opcode.EffectiveOpCode()) {
case OpCode::Id::FMUL_C:
case OpCode::Id::FMUL_R: {
SetDest(0, dest, op_a + " * " + op_b, 1, 1);
case OpCode::Id::FMUL_R:
case OpCode::Id::FMUL_IMM: {
SetDest(0, dest, op_a + " * " + op_b, 1, 1, instr.alu.abs_d);
break;
}
case OpCode::Id::FADD_C:
case OpCode::Id::FADD_R: {
SetDest(0, dest, op_a + " + " + op_b, 1, 1);
case OpCode::Id::FADD_R:
case OpCode::Id::FADD_IMM: {
SetDest(0, dest, op_a + " + " + op_b, 1, 1, instr.alu.abs_d);
break;
}
case OpCode::Id::MUFU: {
@ -316,16 +329,28 @@ private:
std::string dest = GetRegister(instr.gpr0);
std::string op_a = GetRegister(instr.gpr8);
std::string op_b = instr.ffma.negate_b ? "-" : "";
op_b += GetUniform(instr.uniform);
std::string op_c = instr.ffma.negate_c ? "-" : "";
op_c += GetRegister(instr.gpr39);
switch (instr.opcode.EffectiveOpCode()) {
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;
}
default: {
@ -336,6 +361,8 @@ private:
break;
}
}
SetDest(0, dest, op_a + " * " + op_b + " + " + op_c, 1, 1);
break;
}
case OpCode::Type::Memory: {