|
|
|
@ -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: |
|
|
|
|