1
0
Fork 0
forked from suyu/suyu

shader: Account for 33-bit IADD3 scenario

This commit is contained in:
ameerj 2021-06-28 22:38:35 -04:00
parent b21bf79bd2
commit b9069c7891

View file

@ -36,8 +36,12 @@ enum class Half : u64 {
switch (shift) { switch (shift) {
case Shift::None: case Shift::None:
return value; return value;
case Shift::Right: case Shift::Right: {
return ir.ShiftRightLogical(value, ir.Imm32(16)); // 33-bit RS IADD3 edge case
const IR::U1 edge_case{ir.GetCarryFromOp(value)};
const IR::U32 shifted{ir.ShiftRightLogical(value, ir.Imm32(16))};
return IR::U32{ir.Select(edge_case, ir.IAdd(shifted, ir.Imm32(0x10000)), shifted)};
}
case Shift::Left: case Shift::Left:
return ir.ShiftLeftLogical(value, ir.Imm32(16)); return ir.ShiftLeftLogical(value, ir.Imm32(16));
} }
@ -67,6 +71,10 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 o
} }
IR::U32 lhs_1{v.ir.IAdd(op_a, op_b)}; IR::U32 lhs_1{v.ir.IAdd(op_a, op_b)};
if (iadd3.x != 0) { if (iadd3.x != 0) {
// TODO: How does RS behave when X is set?
if (shift == Shift::Right) {
throw NotImplementedException("IADD3 X+RS");
}
const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))}; const IR::U32 carry{v.ir.Select(v.ir.GetCFlag(), v.ir.Imm32(1), v.ir.Imm32(0))};
lhs_1 = v.ir.IAdd(lhs_1, carry); lhs_1 = v.ir.IAdd(lhs_1, carry);
} }