From 2d6c064e66bac4cb871aa26a12066441a8852008 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Thu, 27 Dec 2018 16:50:36 -0300 Subject: shader_decode: Improve zero flag implementation --- .../shader/decode/arithmetic_integer.cpp | 31 ++++++++++------------ 1 file changed, 14 insertions(+), 17 deletions(-) (limited to 'src/video_core/shader/decode/arithmetic_integer.cpp') diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index 931e0fa1d..edd1695f4 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp @@ -34,22 +34,20 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { case OpCode::Id::IADD_C: case OpCode::Id::IADD_R: case OpCode::Id::IADD_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "Condition codes generation in IADD is not implemented"); UNIMPLEMENTED_IF_MSG(instr.alu.saturate_d, "IADD saturation not implemented"); op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true); op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true); - SetRegister(bb, instr.gpr0, Operation(OperationCode::IAdd, PRECISE, op_a, op_b)); + const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b); + + SetInternalFlagsFromInteger(bb, value, instr.op_32.generates_cc); + SetRegister(bb, instr.gpr0, value); break; } case OpCode::Id::IADD3_C: case OpCode::Id::IADD3_R: case OpCode::Id::IADD3_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "Condition codes generation in IADD3 is not implemented"); - Node op_c = GetRegister(instr.gpr39); const auto ApplyHeight = [&](IAdd3Height height, Node value) { @@ -100,6 +98,7 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { return Operation(OperationCode::IAdd, NO_PRECISE, shifted, op_c); }(); + SetInternalFlagsFromInteger(bb, value, instr.generates_cc); SetRegister(bb, instr.gpr0, value); break; } @@ -115,6 +114,8 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { const Node shift = Immediate(static_cast(instr.alu_integer.shift_amount)); const Node shifted_a = Operation(OperationCode::ILogicalShiftLeft, NO_PRECISE, op_a, shift); const Node value = Operation(OperationCode::IAdd, NO_PRECISE, shifted_a, op_b); + + SetInternalFlagsFromInteger(bb, value, instr.generates_cc); SetRegister(bb, instr.gpr0, value); break; } @@ -139,24 +140,19 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { case OpCode::Id::LOP_C: case OpCode::Id::LOP_R: case OpCode::Id::LOP_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "Condition codes generation in LOP is not implemented"); - if (instr.alu.lop.invert_a) op_a = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_a); if (instr.alu.lop.invert_b) op_b = Operation(OperationCode::IBitwiseNot, NO_PRECISE, op_b); WriteLogicOperation(bb, instr.gpr0, instr.alu.lop.operation, op_a, op_b, - instr.alu.lop.pred_result_mode, instr.alu.lop.pred48); + instr.alu.lop.pred_result_mode, instr.alu.lop.pred48, + instr.generates_cc); break; } case OpCode::Id::LOP3_C: case OpCode::Id::LOP3_R: case OpCode::Id::LOP3_IMM: { - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "Condition codes generation in LOP3 is not implemented"); - const Node op_c = GetRegister(instr.gpr39); const Node lut = [&]() { if (opcode->get().GetId() == OpCode::Id::LOP3_R) { @@ -166,15 +162,13 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { } }(); - WriteLop3Instruction(bb, instr.gpr0, op_a, op_b, op_c, lut); + WriteLop3Instruction(bb, instr.gpr0, op_a, op_b, op_c, lut, instr.generates_cc); break; } case OpCode::Id::IMNMX_C: case OpCode::Id::IMNMX_R: case OpCode::Id::IMNMX_IMM: { UNIMPLEMENTED_IF(instr.imnmx.exchange != Tegra::Shader::IMinMaxExchange::None); - UNIMPLEMENTED_IF_MSG(instr.generates_cc, - "Condition codes generation in IMNMX is not implemented"); const bool is_signed = instr.imnmx.is_signed; @@ -182,6 +176,8 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { const Node min = SignedOperation(OperationCode::IMin, is_signed, NO_PRECISE, op_a, op_b); const Node max = SignedOperation(OperationCode::IMax, is_signed, NO_PRECISE, op_a, op_b); const Node value = Operation(OperationCode::Select, NO_PRECISE, condition, min, max); + + SetInternalFlagsFromInteger(bb, value, instr.generates_cc); SetRegister(bb, instr.gpr0, value); break; } @@ -247,7 +243,7 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, u32 pc) { } void ShaderIR::WriteLop3Instruction(BasicBlock& bb, Register dest, Node op_a, Node op_b, Node op_c, - Node imm_lut) { + Node imm_lut, bool sets_cc) { constexpr u32 lop_iterations = 32; const Node one = Immediate(1); const Node two = Immediate(2); @@ -284,6 +280,7 @@ void ShaderIR::WriteLop3Instruction(BasicBlock& bb, Register dest, Node op_a, No } } + SetInternalFlagsFromInteger(bb, value, sets_cc); SetRegister(bb, dest, value); } -- cgit v1.2.3