aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorAlex Coplan <alex.coplan@arm.com>2021-05-17 15:12:39 +0100
committerAlex Coplan <alex.coplan@arm.com>2021-05-17 15:12:39 +0100
commite683cb412046b40085505f42dd141f542661a6ae (patch)
tree5691bbcb60d26278a40eb4265c53db1e0a33af35 /opcodes
parent467f8eb233291031e1883c12fae9c8f41177efa2 (diff)
downloadbinutils-e683cb412046b40085505f42dd141f542661a6ae.zip
binutils-e683cb412046b40085505f42dd141f542661a6ae.tar.gz
binutils-e683cb412046b40085505f42dd141f542661a6ae.tar.bz2
arm: Fix bugs with MVE vmov from two GPRs to vector lanes
The initial problem I wanted to fix here is that GAS was rejecting MVE instructions such as: vmov q3[2], q3[0], r2, r2 with: Error: General purpose registers may not be the same -- `vmov q3[2],q3[0],r2,r2' which is incorrect; such instructions are valid. Note that for moves in the other direction, e.g.: vmov r2, r2, q3[2], q3[0] GAS is correct in rejecting this as it does not make sense to move both lanes into the same register (the Arm ARM says this is CONSTRAINED UNPREDICTABLE). After fixing this issue, I added assembly/disassembly tests for these vmovs. This revealed several disassembly issues, including incorrectly marking the moves into vector lanes as UNPREDICTABLE, and disassembling many of the vmovs as vector loads. These are now fixed. gas/ChangeLog: * config/tc-arm.c (do_mve_mov): Only reject vmov if we're moving into the same GPR twice. * testsuite/gas/arm/mve-vmov-bad-2.l: Tweak error message. * testsuite/gas/arm/mve-vmov-3.d: New test. * testsuite/gas/arm/mve-vmov-3.s: New test. opcodes/ChangeLog: * arm-dis.c (mve_opcodes): Fix disassembly of MVE_VMOV2_GP_TO_VEC_LANE when idx == 1. (is_mve_encoding_conflict): MVE vector loads should not match when P = W = 0. (is_mve_unpredictable): It's not unpredictable to use the same source register twice (for MVE_VMOV2_GP_TO_VEC_LANE).
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog9
-rw-r--r--opcodes/arm-dis.c7
2 files changed, 14 insertions, 2 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 6a4bd6f..d506b71 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,12 @@
+2021-05-17 Alex Coplan <alex.coplan@arm.com>
+
+ * arm-dis.c (mve_opcodes): Fix disassembly of
+ MVE_VMOV2_GP_TO_VEC_LANE when idx == 1.
+ (is_mve_encoding_conflict): MVE vector loads should not match
+ when P = W = 0.
+ (is_mve_unpredictable): It's not unpredictable to use the same
+ source register twice (for MVE_VMOV2_GP_TO_VEC_LANE).
+
2021-05-11 Nick Clifton <nickc@redhat.com>
PR 27840
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 4130919..92cd098 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -2954,7 +2954,7 @@ static const struct mopcode32 mve_opcodes[] =
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE),
MVE_VMOV2_GP_TO_VEC_LANE,
0xec100f10, 0xffb01ff0,
- "vmov%c\t%13-15,22Q[2], %13-15,22Q[0], %0-3r, %16-19r"},
+ "vmov%c\t%13-15,22Q[3], %13-15,22Q[1], %0-3r, %16-19r"},
/* Vector VMOV Vector lane to gpr. */
{ARM_FEATURE_CORE_HIGH (ARM_EXT2_MVE_FP),
@@ -5722,6 +5722,9 @@ is_mve_encoding_conflict (unsigned long given,
else
return false;
+ case MVE_VLDRB_T1:
+ case MVE_VLDRH_T2:
+ case MVE_VLDRW_T7:
case MVE_VSTRB_T5:
case MVE_VSTRH_T6:
case MVE_VSTRW_T7:
@@ -6656,7 +6659,7 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn,
*unpredictable_code = UNPRED_R15;
return true;
}
- else if (rt == rt2)
+ else if (rt == rt2 && matched_insn != MVE_VMOV2_GP_TO_VEC_LANE)
{
*unpredictable_code = UNPRED_GP_REGS_EQUAL;
return true;