shader: Implement LOP32I
This commit is contained in:
		| @@ -32,34 +32,51 @@ enum class LogicalOp : u64 { | ||||
|     } | ||||
| } | ||||
|  | ||||
| void LOP(TranslatorVisitor& v, u64 insn, IR::U32 op_b) { | ||||
| void LOP(TranslatorVisitor& v, u64 insn, IR::U32 op_b, bool x, bool cc, bool inv_a, bool inv_b, | ||||
|          LogicalOp bit_op, std::optional<PredicateOp> pred_op = std::nullopt, | ||||
|          IR::Pred dest_pred = IR::Pred::PT) { | ||||
|     union { | ||||
|         u64 insn; | ||||
|         BitField<0, 8, IR::Reg> dest_reg; | ||||
|         BitField<8, 8, IR::Reg> src_reg; | ||||
|         BitField<39, 1, u64> neg_a; | ||||
|         BitField<40, 1, u64> neg_b; | ||||
|         BitField<41, 2, LogicalOp> bit_op; | ||||
|         BitField<43, 1, u64> x; | ||||
|         BitField<44, 2, PredicateOp> pred_op; | ||||
|         BitField<48, 3, IR::Pred> pred; | ||||
|     } const lop{insn}; | ||||
|  | ||||
|     if (lop.x != 0) { | ||||
|         throw NotImplementedException("LOP X"); | ||||
|     if (x) { | ||||
|         throw NotImplementedException("X"); | ||||
|     } | ||||
|     if (cc) { | ||||
|         throw NotImplementedException("CC"); | ||||
|     } | ||||
|     IR::U32 op_a{v.X(lop.src_reg)}; | ||||
|     if (lop.neg_a != 0) { | ||||
|     if (inv_a != 0) { | ||||
|         op_a = v.ir.BitwiseNot(op_a); | ||||
|     } | ||||
|     if (lop.neg_b != 0) { | ||||
|     if (inv_b != 0) { | ||||
|         op_b = v.ir.BitwiseNot(op_b); | ||||
|     } | ||||
|  | ||||
|     const IR::U32 result{LogicalOperation(v.ir, op_a, op_b, lop.bit_op)}; | ||||
|     const IR::U1 pred_result{PredicateOperation(v.ir, result, lop.pred_op)}; | ||||
|     const IR::U32 result{LogicalOperation(v.ir, op_a, op_b, bit_op)}; | ||||
|     if (pred_op) { | ||||
|         const IR::U1 pred_result{PredicateOperation(v.ir, result, *pred_op)}; | ||||
|         v.ir.SetPred(dest_pred, pred_result); | ||||
|     } | ||||
|     v.X(lop.dest_reg, result); | ||||
|     v.ir.SetPred(lop.pred, pred_result); | ||||
| } | ||||
|  | ||||
| void LOP(TranslatorVisitor& v, u64 insn, const IR::U32& op_b) { | ||||
|     union { | ||||
|         u64 insn; | ||||
|         BitField<39, 1, u64> inv_a; | ||||
|         BitField<40, 1, u64> inv_b; | ||||
|         BitField<41, 2, LogicalOp> bit_op; | ||||
|         BitField<43, 1, u64> x; | ||||
|         BitField<44, 2, PredicateOp> pred_op; | ||||
|         BitField<47, 1, u64> cc; | ||||
|         BitField<48, 3, IR::Pred> dest_pred; | ||||
|     } const lop{insn}; | ||||
|  | ||||
|     LOP(v, insn, op_b, lop.x != 0, lop.cc != 0, lop.inv_a != 0, lop.inv_b != 0, lop.bit_op, | ||||
|         lop.pred_op, lop.dest_pred); | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| @@ -74,4 +91,18 @@ void TranslatorVisitor::LOP_cbuf(u64 insn) { | ||||
| void TranslatorVisitor::LOP_imm(u64 insn) { | ||||
|     LOP(*this, insn, GetImm20(insn)); | ||||
| } | ||||
|  | ||||
| void TranslatorVisitor::LOP32I(u64 insn) { | ||||
|     union { | ||||
|         u64 raw; | ||||
|         BitField<53, 2, LogicalOp> bit_op; | ||||
|         BitField<57, 1, u64> x; | ||||
|         BitField<52, 1, u64> cc; | ||||
|         BitField<55, 1, u64> inv_a; | ||||
|         BitField<56, 1, u64> inv_b; | ||||
|     } const lop32i{insn}; | ||||
|  | ||||
|     LOP(*this, insn, GetImm32(insn), lop32i.x != 0, lop32i.cc != 0, lop32i.inv_a != 0, | ||||
|         lop32i.inv_b != 0, lop32i.bit_op); | ||||
| } | ||||
| } // namespace Shader::Maxwell | ||||
|   | ||||
| @@ -357,10 +357,6 @@ void TranslatorVisitor::LONGJMP(u64) { | ||||
|     ThrowNotImplemented(Opcode::LONGJMP); | ||||
| } | ||||
|  | ||||
| void TranslatorVisitor::LOP32I(u64) { | ||||
|     ThrowNotImplemented(Opcode::LOP32I); | ||||
| } | ||||
|  | ||||
| void TranslatorVisitor::MEMBAR(u64) { | ||||
|     ThrowNotImplemented(Opcode::MEMBAR); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user