aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmc28a <78873583+mmc28a@users.noreply.github.com>2024-05-16 15:27:20 +0100
committerGitHub <noreply@github.com>2024-05-16 15:27:20 +0100
commit2cdba9ed4a1ee6872e513768311cc03ad68b315c (patch)
treec25f8813720bc573d8f9b9827a8df6456c7c6b0c
parent3134e2560de12dfebbd72ef4868b2a5c5d7b5da9 (diff)
downloadvixl-upstream-main.tar.gz
Fix zeroing part of SVE register for Neon INS (#95)upstream-main
The INS instruction inserts an element into an existing 128-bit vector, but for systems with larger SVE registers, bits beyond the end of the vector must be zeroed. Fix this and add a regression test.
-rw-r--r--src/aarch64/simulator-aarch64.cc2
-rw-r--r--test/aarch64/test-assembler-sve-aarch64.cc20
-rw-r--r--tools/code_coverage.log3
3 files changed, 24 insertions, 1 deletions
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index 3624f257..52a9cb8b 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -8320,8 +8320,10 @@ void Simulator::VisitNEONCopy(const Instruction* instr) {
if (instr->Mask(NEONCopyInsElementMask) == NEON_INS_ELEMENT) {
int imm4 = instr->GetImmNEON4();
int rn_index = ExtractSignedBitfield32(31, tz, imm4);
+ mov(kFormat16B, rd, rd); // Zero bits beyond the MSB of a Q register.
ins_element(vf, rd, reg_index, rn, rn_index);
} else if (instr->Mask(NEONCopyInsGeneralMask) == NEON_INS_GENERAL) {
+ mov(kFormat16B, rd, rd); // Zero bits beyond the MSB of a Q register.
ins_immediate(vf, rd, reg_index, ReadXRegister(instr->GetRn()));
} else if (instr->Mask(NEONCopyUmovMask) == NEON_UMOV) {
uint64_t value = LogicVRegister(rn).Uint(vf, reg_index);
diff --git a/test/aarch64/test-assembler-sve-aarch64.cc b/test/aarch64/test-assembler-sve-aarch64.cc
index f16ab336..fdbcdf99 100644
--- a/test/aarch64/test-assembler-sve-aarch64.cc
+++ b/test/aarch64/test-assembler-sve-aarch64.cc
@@ -19729,6 +19729,26 @@ TEST_SVE(sudot_usdot) {
}
}
+TEST_SVE(neon_ins_zero_high_regression_test) {
+ SVE_SETUP_WITH_FEATURES(CPUFeatures::kNEON, CPUFeatures::kSVE);
+
+ START();
+ __ Movi(v0.V2D(), 0x0f0e0d0c0b0a0908, 0x0706050403020100);
+
+ // Check that both forms of ins zero bits <VL-1:128>
+ __ Index(z1.VnB(), 0, 1);
+ __ Ins(v1.V16B(), 0, wzr);
+ __ Index(z2.VnB(), 0, 1);
+ __ Ins(v2.V16B(), 3, v2.V16B(), 3);
+ END();
+
+ if (CAN_RUN()) {
+ RUN();
+ ASSERT_EQUAL_SVE(z0, z1);
+ ASSERT_EQUAL_SVE(z0, z2);
+ }
+}
+
TEST_SVE(sve_load_store_sp_base_regression_test) {
SVE_SETUP_WITH_FEATURES(CPUFeatures::kSVE);
START();
diff --git a/tools/code_coverage.log b/tools/code_coverage.log
index 3f459e44..0a5969b3 100644
--- a/tools/code_coverage.log
+++ b/tools/code_coverage.log
@@ -22,4 +22,5 @@
1693487542 82.91% 97.57% 94.87%
1702052331 82.89% 97.59% 94.77%
1706691191 82.87% 97.59% 94.74%
-1707395574 82.89% 97.59% 94.77% \ No newline at end of file
+1707395574 82.89% 97.59% 94.77%
+1715261843 82.84% 97.60% 94.69%