shader: Implement IADD3
This commit is contained in:
parent
c2155f04d4
commit
382cba94ed
3 changed files with 104 additions and 12 deletions
|
@ -74,6 +74,7 @@ add_library(shader_recompiler STATIC
|
|||
frontend/maxwell/translate/impl/impl.cpp
|
||||
frontend/maxwell/translate/impl/impl.h
|
||||
frontend/maxwell/translate/impl/integer_add.cpp
|
||||
frontend/maxwell/translate/impl/integer_add_three_input.cpp
|
||||
frontend/maxwell/translate/impl/integer_compare.cpp
|
||||
frontend/maxwell/translate/impl/integer_compare_and_set.cpp
|
||||
frontend/maxwell/translate/impl/integer_minimum_maximum.cpp
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "shader_recompiler/frontend/maxwell/translate/impl/impl.h"
|
||||
|
||||
namespace Shader::Maxwell {
|
||||
namespace {
|
||||
enum class Shift : u64 {
|
||||
None,
|
||||
Right,
|
||||
Left,
|
||||
};
|
||||
enum class Half : u64 {
|
||||
All,
|
||||
Lower,
|
||||
Upper,
|
||||
};
|
||||
|
||||
[[nodiscard]] IR::U32 IntegerHalf(IR::IREmitter& ir, const IR::U32& value, Half half) {
|
||||
constexpr bool is_signed{false};
|
||||
switch (half) {
|
||||
case Half::Lower:
|
||||
return ir.BitFieldExtract(value, ir.Imm32(0), ir.Imm32(16), is_signed);
|
||||
case Half::Upper:
|
||||
return ir.BitFieldExtract(value, ir.Imm32(16), ir.Imm32(16), is_signed);
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] IR::U32 IntegerShift(IR::IREmitter& ir, const IR::U32& value, Shift shift) {
|
||||
switch (shift) {
|
||||
case Shift::Right:
|
||||
return ir.ShiftRightLogical(value, ir.Imm32(16));
|
||||
case Shift::Left:
|
||||
return ir.ShiftLeftLogical(value, ir.Imm32(16));
|
||||
default:
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
void IADD3(TranslatorVisitor& v, u64 insn, IR::U32 op_b, IR::U32 op_c) {
|
||||
union {
|
||||
u64 insn;
|
||||
BitField<0, 8, IR::Reg> dest_reg;
|
||||
BitField<8, 8, IR::Reg> src_a;
|
||||
BitField<31, 2, Half> half_c;
|
||||
BitField<33, 2, Half> half_b;
|
||||
BitField<35, 2, Half> half_a;
|
||||
BitField<37, 2, Shift> shift;
|
||||
BitField<47, 1, u64> cc;
|
||||
BitField<48, 1, u64> x;
|
||||
BitField<49, 1, u64> neg_c;
|
||||
BitField<50, 1, u64> neg_b;
|
||||
BitField<51, 1, u64> neg_a;
|
||||
} iadd3{insn};
|
||||
|
||||
if (iadd3.x != 0) {
|
||||
throw NotImplementedException("IADD3 X");
|
||||
}
|
||||
if (iadd3.cc != 0) {
|
||||
throw NotImplementedException("IADD3 CC");
|
||||
}
|
||||
|
||||
IR::U32 op_a{v.X(iadd3.src_a)};
|
||||
op_a = IntegerHalf(v.ir, op_a, iadd3.half_a);
|
||||
op_b = IntegerHalf(v.ir, op_b, iadd3.half_b);
|
||||
op_c = IntegerHalf(v.ir, op_c, iadd3.half_c);
|
||||
|
||||
if (iadd3.neg_a != 0) {
|
||||
op_a = v.ir.INeg(op_a);
|
||||
}
|
||||
if (iadd3.neg_b != 0) {
|
||||
op_b = v.ir.INeg(op_b);
|
||||
}
|
||||
if (iadd3.neg_c != 0) {
|
||||
op_c = v.ir.INeg(op_c);
|
||||
}
|
||||
|
||||
IR::U32 lhs{v.ir.IAdd(op_a, op_b)};
|
||||
lhs = IntegerShift(v.ir, lhs, iadd3.shift);
|
||||
const IR::U32 result{v.ir.IAdd(lhs, op_c)};
|
||||
|
||||
v.X(iadd3.dest_reg, result);
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
void TranslatorVisitor::IADD3_reg(u64 insn) {
|
||||
IADD3(*this, insn, GetReg20(insn), GetReg39(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD3_cbuf(u64 insn) {
|
||||
IADD3(*this, insn, GetCbuf(insn), GetReg39(insn));
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD3_imm(u64 insn) {
|
||||
IADD3(*this, insn, GetImm20(insn), GetReg39(insn));
|
||||
}
|
||||
|
||||
} // namespace Shader::Maxwell
|
|
@ -365,18 +365,6 @@ void TranslatorVisitor::I2I_imm(u64) {
|
|||
ThrowNotImplemented(Opcode::I2I_imm);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD3_reg(u64) {
|
||||
ThrowNotImplemented(Opcode::IADD3_reg);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD3_cbuf(u64) {
|
||||
ThrowNotImplemented(Opcode::IADD3_cbuf);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IADD3_imm(u64) {
|
||||
ThrowNotImplemented(Opcode::IADD3_imm);
|
||||
}
|
||||
|
||||
void TranslatorVisitor::IDE(u64) {
|
||||
ThrowNotImplemented(Opcode::IDE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue