diff options
Diffstat (limited to 'src/shader_recompiler/frontend/maxwell/translate/impl')
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation.cpp | 59 | ||||
| -rw-r--r-- | src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | 4 |
2 files changed, 45 insertions, 18 deletions
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation.cpp index e786a388e..89e5cd6de 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/logic_operation.cpp | |||
| @@ -32,34 +32,51 @@ enum class LogicalOp : u64 { | |||
| 32 | } | 32 | } |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | void LOP(TranslatorVisitor& v, u64 insn, IR::U32 op_b) { | 35 | void LOP(TranslatorVisitor& v, u64 insn, IR::U32 op_b, bool x, bool cc, bool inv_a, bool inv_b, |
| 36 | LogicalOp bit_op, std::optional<PredicateOp> pred_op = std::nullopt, | ||
| 37 | IR::Pred dest_pred = IR::Pred::PT) { | ||
| 36 | union { | 38 | union { |
| 37 | u64 insn; | 39 | u64 insn; |
| 38 | BitField<0, 8, IR::Reg> dest_reg; | 40 | BitField<0, 8, IR::Reg> dest_reg; |
| 39 | BitField<8, 8, IR::Reg> src_reg; | 41 | BitField<8, 8, IR::Reg> src_reg; |
| 40 | BitField<39, 1, u64> neg_a; | ||
| 41 | BitField<40, 1, u64> neg_b; | ||
| 42 | BitField<41, 2, LogicalOp> bit_op; | ||
| 43 | BitField<43, 1, u64> x; | ||
| 44 | BitField<44, 2, PredicateOp> pred_op; | ||
| 45 | BitField<48, 3, IR::Pred> pred; | ||
| 46 | } const lop{insn}; | 42 | } const lop{insn}; |
| 47 | 43 | ||
| 48 | if (lop.x != 0) { | 44 | if (x) { |
| 49 | throw NotImplementedException("LOP X"); | 45 | throw NotImplementedException("X"); |
| 46 | } | ||
| 47 | if (cc) { | ||
| 48 | throw NotImplementedException("CC"); | ||
| 50 | } | 49 | } |
| 51 | IR::U32 op_a{v.X(lop.src_reg)}; | 50 | IR::U32 op_a{v.X(lop.src_reg)}; |
| 52 | if (lop.neg_a != 0) { | 51 | if (inv_a != 0) { |
| 53 | op_a = v.ir.BitwiseNot(op_a); | 52 | op_a = v.ir.BitwiseNot(op_a); |
| 54 | } | 53 | } |
| 55 | if (lop.neg_b != 0) { | 54 | if (inv_b != 0) { |
| 56 | op_b = v.ir.BitwiseNot(op_b); | 55 | op_b = v.ir.BitwiseNot(op_b); |
| 57 | } | 56 | } |
| 58 | 57 | ||
| 59 | const IR::U32 result{LogicalOperation(v.ir, op_a, op_b, lop.bit_op)}; | 58 | const IR::U32 result{LogicalOperation(v.ir, op_a, op_b, bit_op)}; |
| 60 | const IR::U1 pred_result{PredicateOperation(v.ir, result, lop.pred_op)}; | 59 | if (pred_op) { |
| 60 | const IR::U1 pred_result{PredicateOperation(v.ir, result, *pred_op)}; | ||
| 61 | v.ir.SetPred(dest_pred, pred_result); | ||
| 62 | } | ||
| 61 | v.X(lop.dest_reg, result); | 63 | v.X(lop.dest_reg, result); |
| 62 | v.ir.SetPred(lop.pred, pred_result); | 64 | } |
| 65 | |||
| 66 | void LOP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) { | ||
| 67 | union { | ||
| 68 | u64 insn; | ||
| 69 | BitField<39, 1, u64> inv_a; | ||
| 70 | BitField<40, 1, u64> inv_b; | ||
| 71 | BitField<41, 2, LogicalOp> bit_op; | ||
| 72 | BitField<43, 1, u64> x; | ||
| 73 | BitField<44, 2, PredicateOp> pred_op; | ||
| 74 | BitField<47, 1, u64> cc; | ||
| 75 | BitField<48, 3, IR::Pred> dest_pred; | ||
| 76 | } const lop{insn}; | ||
| 77 | |||
| 78 | LOP(v, insn, op_b, lop.x != 0, lop.cc != 0, lop.inv_a != 0, lop.inv_b != 0, lop.bit_op, | ||
| 79 | lop.pred_op, lop.dest_pred); | ||
| 63 | } | 80 | } |
| 64 | } // Anonymous namespace | 81 | } // Anonymous namespace |
| 65 | 82 | ||
| @@ -74,4 +91,18 @@ void TranslatorVisitor::LOP_cbuf(u64 insn) { | |||
| 74 | void TranslatorVisitor::LOP_imm(u64 insn) { | 91 | void TranslatorVisitor::LOP_imm(u64 insn) { |
| 75 | LOP(*this, insn, GetImm20(insn)); | 92 | LOP(*this, insn, GetImm20(insn)); |
| 76 | } | 93 | } |
| 94 | |||
| 95 | void TranslatorVisitor::LOP32I(u64 insn) { | ||
| 96 | union { | ||
| 97 | u64 raw; | ||
| 98 | BitField<53, 2, LogicalOp> bit_op; | ||
| 99 | BitField<57, 1, u64> x; | ||
| 100 | BitField<52, 1, u64> cc; | ||
| 101 | BitField<55, 1, u64> inv_a; | ||
| 102 | BitField<56, 1, u64> inv_b; | ||
| 103 | } const lop32i{insn}; | ||
| 104 | |||
| 105 | LOP(*this, insn, GetImm32(insn), lop32i.x != 0, lop32i.cc != 0, lop32i.inv_a != 0, | ||
| 106 | lop32i.inv_b != 0, lop32i.bit_op); | ||
| 107 | } | ||
| 77 | } // namespace Shader::Maxwell | 108 | } // namespace Shader::Maxwell |
diff --git a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp index 59252bcc5..a4367fc5a 100644 --- a/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp +++ b/src/shader_recompiler/frontend/maxwell/translate/impl/not_implemented.cpp | |||
| @@ -357,10 +357,6 @@ void TranslatorVisitor::LONGJMP(u64) { | |||
| 357 | ThrowNotImplemented(Opcode::LONGJMP); | 357 | ThrowNotImplemented(Opcode::LONGJMP); |
| 358 | } | 358 | } |
| 359 | 359 | ||
| 360 | void TranslatorVisitor::LOP32I(u64) { | ||
| 361 | ThrowNotImplemented(Opcode::LOP32I); | ||
| 362 | } | ||
| 363 | |||
| 364 | void TranslatorVisitor::MEMBAR(u64) { | 360 | void TranslatorVisitor::MEMBAR(u64) { |
| 365 | ThrowNotImplemented(Opcode::MEMBAR); | 361 | ThrowNotImplemented(Opcode::MEMBAR); |
| 366 | } | 362 | } |