mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-22 03:46:53 +02:00
shader: compute scalar signed-overflow and shift-add carry SCC with fewer ops
This commit is contained in:
@@ -140,29 +140,23 @@ void Translator::S_ABSDIFF_I32(const Decoder::Instruction& inst) {
|
||||
}
|
||||
|
||||
void Translator::S_ADD_SUB_I32(const Decoder::Instruction& inst, bool subtract) {
|
||||
const auto lhs = ReadU32(inst.src0);
|
||||
const auto rhs = ReadU32(inst.src1);
|
||||
const auto result = subtract ? ir.ISub(lhs, rhs) : ir.IAdd(lhs, rhs);
|
||||
const auto shift = IR::U32(IR::Value(31u));
|
||||
const auto lhs_sign = ir.ShiftRightLogical(lhs, shift);
|
||||
const auto rhs_sign = ir.ShiftRightLogical(rhs, shift);
|
||||
const auto out_sign = ir.ShiftRightLogical(result, shift);
|
||||
const auto inputs = subtract ? ir.INotEqual(lhs_sign, rhs_sign) : ir.IEqual(lhs_sign, rhs_sign);
|
||||
const auto changed = ir.INotEqual(lhs_sign, out_sign);
|
||||
const auto lhs = ReadU32(inst.src0);
|
||||
const auto rhs = ReadU32(inst.src1);
|
||||
const auto result = subtract ? ir.ISub(lhs, rhs) : ir.IAdd(lhs, rhs);
|
||||
// Overflow sets the sign bit of lhs ^ result and of rhs ^ result (add) or lhs ^ rhs (sub).
|
||||
const auto other = subtract ? ir.BitwiseXor(lhs, rhs) : ir.BitwiseXor(rhs, result);
|
||||
const auto overflow = ir.BitwiseAnd(ir.BitwiseXor(lhs, result), other);
|
||||
WriteOperand(DestinationOperand(inst), result);
|
||||
ir.SetScc(ir.LogicalAnd(inputs, changed));
|
||||
ir.SetScc(ir.UGreaterThan(overflow, IR::U32(IR::Value(0x7fffffffu))));
|
||||
}
|
||||
|
||||
void Translator::S_LSHL_ADD_U32(const Decoder::Instruction& inst, uint32_t shift_amount) {
|
||||
const auto lhs = ReadU32(inst.src0);
|
||||
const auto shift = IR::U32(IR::Value(shift_amount));
|
||||
const auto rhs = ReadU32(inst.src1);
|
||||
const auto shifted = ir.ShiftLeftLogical(lhs, shift);
|
||||
const auto result = ir.IAdd(shifted, rhs);
|
||||
const auto add_carry = ir.ULessThan(result, shifted);
|
||||
const auto inverse_shift = ir.ISub(IR::U32(IR::Value(32u)), shift);
|
||||
const auto shifted_out = ir.ShiftRightLogical(lhs, inverse_shift);
|
||||
const auto shift_carry = ir.INotEqual(shifted_out, IR::U32(IR::Value(0u)));
|
||||
const auto lhs = ReadU32(inst.src0);
|
||||
const auto rhs = ReadU32(inst.src1);
|
||||
const auto shifted = ir.ShiftLeftLogical(lhs, IR::U32(IR::Value(shift_amount)));
|
||||
const auto result = ir.IAdd(shifted, rhs);
|
||||
const auto add_carry = ir.ULessThan(result, shifted);
|
||||
const auto shift_carry = ir.UGreaterThan(lhs, IR::U32(IR::Value(~0u >> shift_amount)));
|
||||
WriteOperand(DestinationOperand(inst), result);
|
||||
ir.SetScc(ir.LogicalOr(add_carry, shift_carry));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user