shader/arithmetic_integer: Implement CC for IADD

This commit is contained in:
ReinUsesLisp 2020-04-25 21:56:11 -03:00
parent ffc5ec6fa8
commit 255197e643
5 changed files with 43 additions and 4 deletions

2
externals/sirit vendored

@ -1 +1 @@
Subproject commit a712959f1e373a33b48042b5934e288a243d5954
Subproject commit 414fc4dbd28d8fe48f735a0c389db8a234f733c0

View file

@ -1870,6 +1870,14 @@ private:
return GenerateBinaryInfix(operation, ">=", Type::Bool, type, type);
}
Expression LogicalAddCarry(Operation operation) {
const std::string carry = code.GenerateTemporary();
code.AddLine("uint {};", carry);
code.AddLine("uaddCarry({}, {}, {});", VisitOperand(operation, 0).AsUint(),
VisitOperand(operation, 1).AsUint(), carry);
return {fmt::format("({} != 0)", carry), Type::Bool};
}
Expression LogicalFIsNan(Operation operation) {
return GenerateUnary(operation, "isnan", Type::Bool, Type::Float);
}
@ -2441,6 +2449,8 @@ private:
&GLSLDecompiler::LogicalNotEqual<Type::Uint>,
&GLSLDecompiler::LogicalGreaterEqual<Type::Uint>,
&GLSLDecompiler::LogicalAddCarry,
&GLSLDecompiler::Logical2HLessThan<false>,
&GLSLDecompiler::Logical2HEqual<false>,
&GLSLDecompiler::Logical2HLessEqual<false>,

View file

@ -1584,6 +1584,15 @@ private:
return {OpCompositeConstruct(t_half, low, high), Type::HalfFloat};
}
Expression LogicalAddCarry(Operation operation) {
const Id op_a = AsUint(Visit(operation[0]));
const Id op_b = AsUint(Visit(operation[1]));
const Id result = OpIAddCarry(TypeStruct({t_uint, t_uint}), op_a, op_b);
const Id carry = OpCompositeExtract(t_uint, result, 1);
return {OpINotEqual(t_bool, carry, Constant(t_uint, 0)), Type::Bool};
}
Expression LogicalAssign(Operation operation) {
const Node& dest = operation[0];
const Node& src = operation[1];
@ -2518,6 +2527,8 @@ private:
&SPIRVDecompiler::Binary<&Module::OpINotEqual, Type::Bool, Type::Uint>,
&SPIRVDecompiler::Binary<&Module::OpUGreaterThanEqual, Type::Bool, Type::Uint>,
&SPIRVDecompiler::LogicalAddCarry,
&SPIRVDecompiler::Binary<&Module::OpFOrdLessThan, Type::Bool2, Type::HalfFloat>,
&SPIRVDecompiler::Binary<&Module::OpFOrdEqual, Type::Bool2, Type::HalfFloat>,
&SPIRVDecompiler::Binary<&Module::OpFOrdLessThanEqual, Type::Bool2, Type::HalfFloat>,

View file

@ -40,10 +40,26 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
op_a = GetOperandAbsNegInteger(op_a, false, instr.alu_integer.negate_a, true);
op_b = GetOperandAbsNegInteger(op_b, false, instr.alu_integer.negate_b, true);
const Node value = Operation(OperationCode::IAdd, PRECISE, op_a, op_b);
Node value = Operation(OperationCode::IAdd, op_a, op_b);
SetInternalFlagsFromInteger(bb, value, instr.generates_cc);
SetRegister(bb, instr.gpr0, value);
if (instr.generates_cc) {
const Node i0 = Immediate(0);
Node zero = Operation(OperationCode::LogicalIEqual, value, i0);
Node sign = Operation(OperationCode::LogicalILessThan, value, i0);
Node carry = Operation(OperationCode::LogicalAddCarry, op_a, op_b);
Node pos_a = Operation(OperationCode::LogicalIGreaterThan, op_a, i0);
Node pos_b = Operation(OperationCode::LogicalIGreaterThan, op_b, i0);
Node pos = Operation(OperationCode::LogicalAnd, std::move(pos_a), std::move(pos_b));
Node overflow = Operation(OperationCode::LogicalAnd, pos, sign);
SetInternalFlag(bb, InternalFlag::Zero, std::move(zero));
SetInternalFlag(bb, InternalFlag::Sign, std::move(sign));
SetInternalFlag(bb, InternalFlag::Carry, std::move(carry));
SetInternalFlag(bb, InternalFlag::Overflow, std::move(overflow));
}
SetRegister(bb, instr.gpr0, std::move(value));
break;
}
case OpCode::Id::IADD3_C:

View file

@ -132,6 +132,8 @@ enum class OperationCode {
LogicalUNotEqual, /// (uint a, uint b) -> bool
LogicalUGreaterEqual, /// (uint a, uint b) -> bool
LogicalAddCarry, /// (uint a, uint b) -> bool
Logical2HLessThan, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
Logical2HEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2
Logical2HLessEqual, /// (MetaHalfArithmetic, f16vec2 a, f16vec2) -> bool2