Merge pull request #1763 from ReinUsesLisp/bfi

gl_shader_decompiler: Implement BFI_IMM_R
This commit is contained in:
bunnei 2018-11-25 23:04:57 -05:00 committed by GitHub
commit f9a211220c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 0 deletions

View File

@ -1269,6 +1269,7 @@ public:
BFE_C, BFE_C,
BFE_R, BFE_R,
BFE_IMM, BFE_IMM,
BFI_IMM_R,
BRA, BRA,
PBK, PBK,
LD_A, LD_A,
@ -1410,6 +1411,7 @@ public:
ArithmeticHalf, ArithmeticHalf,
ArithmeticHalfImmediate, ArithmeticHalfImmediate,
Bfe, Bfe,
Bfi,
Shift, Shift,
Ffma, Ffma,
Hfma2, Hfma2,
@ -1628,6 +1630,7 @@ private:
INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"), INST("0100110000000---", Id::BFE_C, Type::Bfe, "BFE_C"),
INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"), INST("0101110000000---", Id::BFE_R, Type::Bfe, "BFE_R"),
INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"), INST("0011100-00000---", Id::BFE_IMM, Type::Bfe, "BFE_IMM"),
INST("0011011-11110---", Id::BFI_IMM_R, Type::Bfi, "BFI_IMM_R"),
INST("0100110001000---", Id::LOP_C, Type::ArithmeticInteger, "LOP_C"), INST("0100110001000---", Id::LOP_C, Type::ArithmeticInteger, "LOP_C"),
INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"), INST("0101110001000---", Id::LOP_R, Type::ArithmeticInteger, "LOP_R"),
INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"), INST("0011100001000---", Id::LOP_IMM, Type::ArithmeticInteger, "LOP_IMM"),

View File

@ -1721,6 +1721,26 @@ private:
break; break;
} }
case OpCode::Type::Bfi: {
UNIMPLEMENTED_IF(instr.generates_cc);
const auto [base, packed_shift] = [&]() -> std::tuple<std::string, std::string> {
switch (opcode->get().GetId()) {
case OpCode::Id::BFI_IMM_R:
return {regs.GetRegisterAsInteger(instr.gpr39, 0, false),
std::to_string(instr.alu.GetSignedImm20_20())};
default:
UNREACHABLE();
}
}();
const std::string offset = '(' + packed_shift + " & 0xff)";
const std::string bits = "((" + packed_shift + " >> 8) & 0xff)";
const std::string insert = regs.GetRegisterAsInteger(instr.gpr8, 0, false);
regs.SetRegisterToInteger(
instr.gpr0, false, 0,
"bitfieldInsert(" + base + ", " + insert + ", " + offset + ", " + bits + ')', 1, 1);
break;
}
case OpCode::Type::Shift: { case OpCode::Type::Shift: {
std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, true); std::string op_a = regs.GetRegisterAsInteger(instr.gpr8, 0, true);
std::string op_b; std::string op_b;