shader: Only apply shift on register mode for IADD3

This commit is contained in:
ReinUsesLisp 2021-06-28 22:35:31 -03:00 committed by ameerj
parent fba6bd92d4
commit b21bf79bd2

View File

@ -22,31 +22,33 @@ enum class Half : u64 {
[[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) { [[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) {
constexpr bool is_signed{false}; constexpr bool is_signed{false};
switch (half) { switch (half) {
case Half::All:
return value;
case Half::Lower: case Half::Lower:
return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed); return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed);
case Half::Upper: case Half::Upper:
return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed); return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed);
default:
return value;
} }
throw NotImplementedException("Invalid half");
} }
[[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) { [[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) {
switch (shift) { switch (shift) {
case Shift::None:
return value;
case Shift::Right: case Shift::Right:
return ir.ShiftRightLogical(value, ir.Imm32(16)); return ir.ShiftRightLogical(value, ir.Imm32(16));
case Shift::Left: case Shift::Left:
return ir.ShiftLeftLogical(value, ir.Imm32(16)); return ir.ShiftLeftLogical(value, ir.Imm32(16));
default:
return value;
} }
throw NotImplementedException("Invalid shift");
} }
void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 op_c) { void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 op_c,
Shift shift = Shift::None) {
union { union {
u64 insn; u64 insn;
BitField<0, 8, IR::Reg> dest_reg; BitField<0, 8, IR::Reg> dest_reg;
BitField<37, 2, Shift> shift;
BitField<47, 1, u64> cc; BitField<47, 1, u64> cc;
BitField<48, 1, u64> x; BitField<48, 1, u64> x;
BitField<49, 1, u64> neg_c; BitField<49, 1, u64> neg_c;
@ -68,7 +70,7 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 o
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);
} }
const IR::U32 lhs_2{IntegerShift(v.ir, lhs_1, iadd3.shift)}; const IR::U32 lhs_2{IntegerShift(v.ir, lhs_1, shift)};
const IR::U32 result{v.ir.IAdd(lhs_2, op_c)}; const IR::U32 result{v.ir.IAdd(lhs_2, op_c)};
v.X(iadd3.dest_reg, result); v.X(iadd3.dest_reg, result);
@ -89,14 +91,16 @@ void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_a, IR::U32 op_b, IR::U32 o
void TranslatorVisitor::IADD3_reg(u64 insn) { void TranslatorVisitor::IADD3_reg(u64 insn) {
union { union {
u64 insn; u64 insn;
BitField<37, 2, Shift> shift;
BitField<35, 2, Half> half_a; BitField<35, 2, Half> half_a;
BitField<31, 2, Half> half_c;
BitField<33, 2, Half> half_b; BitField<33, 2, Half> half_b;
} iadd3{insn}; BitField<31, 2, Half> half_c;
} const iadd3{insn};
const auto op_a{IntegerHalf(ir, GetReg8(insn), iadd3.half_a)}; const auto op_a{IntegerHalf(ir, GetReg8(insn), iadd3.half_a)};
const auto op_b{IntegerHalf(ir, GetReg20(insn), iadd3.half_b)}; const auto op_b{IntegerHalf(ir, GetReg20(insn), iadd3.half_b)};
const auto op_c{IntegerHalf(ir, GetReg39(insn), iadd3.half_c)}; const auto op_c{IntegerHalf(ir, GetReg39(insn), iadd3.half_c)};
IADD3(*this, insn, op_a, op_b, op_c); IADD3(*this, insn, op_a, op_b, op_c, iadd3.shift);
} }
void TranslatorVisitor::IADD3_cbuf(u64 insn) { void TranslatorVisitor::IADD3_cbuf(u64 insn) {