simd_two_register_misc: FNEG (vector) with Q == 0 had dirty upper

This commit is contained in:
MerryMage 2018-09-09 19:55:37 +01:00
parent 5653e7637e
commit b8daa4feac
2 changed files with 23 additions and 1 deletions

View file

@ -460,7 +460,7 @@ bool TranslatorVisitor::FNEG_2(bool Q, bool sz, Vec Vn, Vec Vd) {
const size_t mask_value = esize == 64 ? 0x8000000000000000 : 0x8000000080000000; const size_t mask_value = esize == 64 ? 0x8000000000000000 : 0x8000000080000000;
const IR::U128 operand = V(datasize, Vn); const IR::U128 operand = V(datasize, Vn);
const IR::U128 mask = ir.VectorBroadcast(esize, I(esize, mask_value)); const IR::U128 mask = Q ? ir.VectorBroadcast(esize, I(esize, mask_value)) : ir.VectorBroadcastLower(esize, I(esize, mask_value));
const IR::U128 result = ir.VectorEor(operand, mask); const IR::U128 result = ir.VectorEor(operand, mask);
V(datasize, Vd, result); V(datasize, Vd, result);

View file

@ -8,8 +8,11 @@
#include <dynarmic/A64/exclusive_monitor.h> #include <dynarmic/A64/exclusive_monitor.h>
#include "common/fp/fpsr.h"
#include "testenv.h" #include "testenv.h"
namespace FP = Dynarmic::FP;
TEST_CASE("A64: ADD", "[a64]") { TEST_CASE("A64: ADD", "[a64]") {
A64TestEnv env; A64TestEnv env;
Dynarmic::A64::Jit jit{Dynarmic::A64::UserConfig{&env}}; Dynarmic::A64::Jit jit{Dynarmic::A64::UserConfig{&env}};
@ -450,3 +453,22 @@ TEST_CASE("A64: FMADD (0x80800000)", "[a64]") {
REQUIRE(jit.GetVector(25) == Vector{0x80000000, 0}); REQUIRE(jit.GetVector(25) == Vector{0x80000000, 0});
} }
TEST_CASE("A64: FNEG failed to zero upper", "[a64]") {
A64TestEnv env;
Dynarmic::A64::Jit jit{Dynarmic::A64::UserConfig{&env}};
env.code_mem.emplace_back(0x2ea0fb50); // FNEG.2S V16, V26
env.code_mem.emplace_back(0x2e207a1c); // SQNEG.8B V28, V16
env.code_mem.emplace_back(0x14000000); // B .
jit.SetPC(0);
jit.SetVector(26, {0x071286fde8f34a90, 0x837cffa8be382f60});
jit.SetFpcr(0x01000000);
env.ticks_left = 6;
jit.Run();
REQUIRE(jit.GetVector(28) == Vector{0x79ee7a03980db670, 0});
REQUIRE(FP::FPSR{jit.GetFpsr()}.QC() == false);
}