mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-29 23:41:19 -06:00
V_ADD3_U32 and V_OR3_B32 (#4326)
This commit is contained in:
parent
fba374442c
commit
d47b0524ce
@ -275,6 +275,8 @@ public:
|
||||
void V_MUL_LO_U32(const GcnInst& inst);
|
||||
void V_MUL_HI_U32(bool is_signed, const GcnInst& inst);
|
||||
void V_MAD_U64_U32(const GcnInst& inst);
|
||||
void V_ADD3_U32(const GcnInst& inst);
|
||||
void V_OR3_B32(const GcnInst& inst);
|
||||
|
||||
// Vector interpolation
|
||||
// VINTRP
|
||||
|
||||
@ -456,6 +456,10 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
||||
return V_MUL_HI_U32(true, inst);
|
||||
case Opcode::V_MAD_U64_U32:
|
||||
return V_MAD_U64_U32(inst);
|
||||
case Opcode::V_ADD3_U32:
|
||||
return V_ADD3_U32(inst);
|
||||
case Opcode::V_OR3_B32:
|
||||
return V_OR3_B32(inst);
|
||||
case Opcode::V_NOP:
|
||||
return;
|
||||
default:
|
||||
@ -1548,6 +1552,24 @@ void Translator::V_MAD_U64_U32(const GcnInst& inst) {
|
||||
ir.SetVcc(did_overflow);
|
||||
}
|
||||
|
||||
void Translator::V_ADD3_U32(const GcnInst& inst) {
|
||||
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
|
||||
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
|
||||
const auto src2 = GetSrc<IR::U32>(inst.src[2]);
|
||||
|
||||
SetDst(inst.dst[0], ir.IAdd(src0, ir.IAdd(src1, src2)));
|
||||
}
|
||||
|
||||
void Translator::V_OR3_B32(const GcnInst& inst) {
|
||||
const auto src0 = GetSrc<IR::U32>(inst.src[0]);
|
||||
const auto src1 = GetSrc<IR::U32>(inst.src[1]);
|
||||
const auto src2 = GetSrc<IR::U32>(inst.src[2]);
|
||||
|
||||
const auto result = ir.BitwiseOr(ir.BitwiseOr(src0, src1), src2);
|
||||
|
||||
SetDst(inst.dst[0], result);
|
||||
}
|
||||
|
||||
IR::U32 Translator::GetCarryIn(const GcnInst& inst) {
|
||||
IR::U1 carry;
|
||||
if (inst.src_count == 3) { // VOP3
|
||||
|
||||
@ -161,3 +161,86 @@ TEST_F(GcnTest, min_nan) {
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, add3_u32_1) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{0, 1, 2});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 3);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, add3_u32_2) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
auto big = 2000000000;
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{big, big, big});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0x65A0BC00);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, add3_u32_3) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
auto big = 2000000000;
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetClamp(true).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{big, big, big});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0x65A0BC00);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, add3_u32_4) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_ADD3_U32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetNeg({1,0,0}).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{0, 1, 2});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0x80000003);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, or3_u32_1) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array<u32,3>{0xF0F0F0F0, 0x07070707, 0x11111111});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0xF7F7F7F7);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, or3_u32_2) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0x57575757);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, or3_u32_3) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
auto big = 2000000000;
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetClamp(true).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0x57575757);
|
||||
}
|
||||
|
||||
TEST_F(GcnTest, or3_u32_4) {
|
||||
auto runner = gcn_test::Runner::instance().value();
|
||||
|
||||
auto spirv = TranslateToSpirv(VOP3A(OpcodeVOP3::V_OR3_B32, VOperand8::V0, SOperand9::V0, SOperand9::V1, SOperand9::V2).SetNeg({0,0,1}).Get());
|
||||
auto result = runner->run<u32>(spirv, std::array{0x07070707, 0x11111111, 0x40404040});
|
||||
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(*result, 0xD7575757);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user