mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-22 06:42:46 +01:00
shader/arithmetic_integer: Implement CC for IADD
This commit is contained in:
parent
ffc5ec6fa8
commit
255197e643
5 changed files with 43 additions and 4 deletions
2
externals/sirit
vendored
2
externals/sirit
vendored
|
@ -1 +1 @@
|
|||
Subproject commit a712959f1e373a33b48042b5934e288a243d5954
|
||||
Subproject commit 414fc4dbd28d8fe48f735a0c389db8a234f733c0
|
|
@ -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>,
|
||||
|
|
|
@ -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>,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue