aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartyn Capewell <martyn.capewell@arm.com>2020-08-11 16:19:43 +0100
committerMartyn Capewell <martyn.capewell@arm.com>2020-08-13 14:20:36 +0000
commit8ed835274dc2846cd60d34cdcd79ecfa07ac6ed9 (patch)
tree2da9f40da06da9635241bdf08f72f9cd5e71327d /src
parent32a7cd97fbcef211d5812e2eef2d4dd134f736b0 (diff)
downloadvixl-8ed835274dc2846cd60d34cdcd79ecfa07ac6ed9.tar.gz
[sve] Disallow dup with shift on byte-sized lanes
The Arm ARM states dup-immediate with shift on byte-sized lanes is an undefined encoding, so add assertions in the assembler to disallow this, and handle the encoding appropriately in the disassembler and simulator. Change-Id: Ibce08d2577e2b780dbb7e4fa478d2f8d18e99a39
Diffstat (limited to 'src')
-rw-r--r--src/aarch64/assembler-sve-aarch64.cc1
-rw-r--r--src/aarch64/disasm-aarch64.cc5
-rw-r--r--src/aarch64/simulator-aarch64.cc11
3 files changed, 15 insertions, 2 deletions
diff --git a/src/aarch64/assembler-sve-aarch64.cc b/src/aarch64/assembler-sve-aarch64.cc
index c33e8552..f7cf8b21 100644
--- a/src/aarch64/assembler-sve-aarch64.cc
+++ b/src/aarch64/assembler-sve-aarch64.cc
@@ -3615,6 +3615,7 @@ void Assembler::dup(const ZRegister& zd, int imm8, int shift) {
VIXL_ASSERT(CPUHas(CPUFeatures::kSVE));
ResolveSVEImm8Shift(&imm8, &shift);
+ VIXL_ASSERT((shift < 8) || !zd.IsLaneSizeB());
Instr shift_bit = (shift > 0) ? (1 << 13) : 0;
Emit(DUP_z_i | SVESize(zd) | Rd(zd) | shift_bit | ImmField<12, 5>(imm8));
diff --git a/src/aarch64/disasm-aarch64.cc b/src/aarch64/disasm-aarch64.cc
index 4e2bca35..d8ac2d24 100644
--- a/src/aarch64/disasm-aarch64.cc
+++ b/src/aarch64/disasm-aarch64.cc
@@ -5996,6 +5996,11 @@ void Disassembler::VisitSVEBroadcastIntImm_Unpredicated(
switch (instr->Mask(SVEBroadcastIntImm_UnpredicatedMask)) {
case DUP_z_i:
+ // The encoding of byte-sized lanes with lsl #8 is undefined.
+ if ((instr->GetSVEVectorFormat() == kFormatVnB) &&
+ (instr->ExtractBit(13) == 1))
+ break;
+
// The preferred disassembly for dup is "mov".
mnemonic = "mov";
form = (instr->ExtractBit(13) == 0) ? "'Zd.'t, #'s1205"
diff --git a/src/aarch64/simulator-aarch64.cc b/src/aarch64/simulator-aarch64.cc
index e1026cec..6d6d1677 100644
--- a/src/aarch64/simulator-aarch64.cc
+++ b/src/aarch64/simulator-aarch64.cc
@@ -9474,12 +9474,19 @@ void Simulator::VisitSVEIntAddSubtractImm_Unpredicated(
void Simulator::VisitSVEBroadcastIntImm_Unpredicated(const Instruction* instr) {
SimVRegister& zd = ReadVRegister(instr->GetRd());
+ VectorFormat format = instr->GetSVEVectorFormat();
int64_t imm = instr->GetImmSVEIntWideSigned();
- imm <<= instr->ExtractBit(13) * 8;
+ int shift = instr->ExtractBit(13) * 8;
+ imm *= 1 << shift;
switch (instr->Mask(SVEBroadcastIntImm_UnpredicatedMask)) {
case DUP_z_i:
- dup_immediate(instr->GetSVEVectorFormat(), zd, imm);
+ // The encoding of byte-sized lanes with lsl #8 is undefined.
+ if ((format == kFormatVnB) && (shift == 8)) {
+ VIXL_UNIMPLEMENTED();
+ } else {
+ dup_immediate(format, zd, imm);
+ }
break;
default:
VIXL_UNIMPLEMENTED();