aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorAndre Vieira <andre.simoesdiasvieira@arm.com>2019-04-15 12:18:16 +0100
committerAndre Vieira <andre.simoesdiasvieira@arm.com>2019-04-15 12:32:01 +0100
commitefd6b3591b4bc8440f4145dfc0e6dbfc0545f7d8 (patch)
treec476839cb0a080902c9cdf252c91738216ffa6e1 /opcodes
parent6b0dd094741bc5e9963eabc64a7030783e471941 (diff)
downloadgdb-efd6b3591b4bc8440f4145dfc0e6dbfc0545f7d8.zip
gdb-efd6b3591b4bc8440f4145dfc0e6dbfc0545f7d8.tar.gz
gdb-efd6b3591b4bc8440f4145dfc0e6dbfc0545f7d8.tar.bz2
[binutils, ARM, 15/16] Add support for VSCCLRM
Like for CLRM, this patch aims to share as much logic with the similar looking VLDM/VSTM. This is achieved by adding 2 new enumerator values in enum reg_list_els for the single-precision and double-precision variants of VSCCLRM and extending parse_vfp_reg_list () to deal with these types. These behave like the existing REGLIST_VFP_S and REGLIST_VFP_D types with extra logic to expect VPR as the last element in the register list. The function is algo augmented with a new partial_match parameter to indicate if any register other than VPR had already been parsed in the register list so as to not try parsing the second variant if that's the case and return the right error message. The rest of the patch is the usual encoding function, new disassembler table entries and format specifier and parsing, encoding and disassembling tests. It is worth mentioning that the new entry in the disassembler table was added in the coprocessor-related table despite VSCCLRM always being available even in FPU-less configurations. The main reason for this is that VSCCLRM also match VLDMIA entry and must thus be tried first but coprocessor entries are tried before T32 entries. It also makes sense because it is in the same encoding space as coprocessor and VFP instructions and is thus the natural place for someone to look for this instruction. Note: Both variants of VSCCLRM support D16-D31 registers but Armv8.1-M Mainline overall does not. I have thus decided not to implement support for these registers in order to keep the code simpler. It can always be added later if needed. ChangeLog entries are as follows: *** gas/ChangeLog *** 2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com> * config/tc-arm.c (arm_typed_reg_parse): Fix typo in comment. (enum reg_list_els): New REGLIST_VFP_S_VPR and REGLIST_VFP_D_VPR enumerators. (parse_vfp_reg_list): Add new partial_match parameter. Set *partial_match to TRUE if at least one element in the register list has matched. Add support for REGLIST_VFP_S_VPR and REGLIST_VFP_D_VPR register lists which expect VPR as last element in the list. (s_arm_unwind_save_vfp_armv6): Adapt call to parse_vfp_reg_list to new prototype. (s_arm_unwind_save_vfp): Likewise. (enum operand_parse_code): New OP_VRSDVLST enumerator. (parse_operands): Adapt call to parse_vfp_reg_list to new prototype. Handle new OP_VRSDVLST case. (do_t_vscclrm): New function. (insns): New entry for VSCCLRM instruction. * testsuite/gas/arm/archv8m_1m-cmse-main-bad.s: Add invalid VSCCLRM instructions. * testsuite/gas/arm/archv8m_1m-cmse-main-bad.l: Add error expectations for above instructions. * testsuite/gas/arm/archv8m_1m-cmse-main.s: Add tests for VSCCLRM instruction. * testsuite/gas/arm/archv8m_1m-cmse-main.d: Add expected disassembly for above instructions. *** opcodes/ChangeLog *** 2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com> * arm-dis.c (coprocessor_opcodes): Document new %C format control code. Add new entries for VSCCLRM instruction. (print_insn_coprocessor): Handle new %C format control code.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog6
-rw-r--r--opcodes/arm-dis.c32
2 files changed, 38 insertions, 0 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index c113745..7b330c7 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,11 @@
2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+ * arm-dis.c (coprocessor_opcodes): Document new %C format control code.
+ Add new entries for VSCCLRM instruction.
+ (print_insn_coprocessor): Handle new %C format control code.
+
+2019-04-15 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
* arm-dis.c (enum isa): New enum.
(struct sopcode32): New structure.
(coprocessor_opcodes): change type of entries to struct sopcode32 and
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index dfb6ac7..ea053a3 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -109,6 +109,7 @@ struct opcode16
UNPREDICTABLE if not AL in Thumb)
%A print address for ldc/stc/ldf/stf instruction
%B print vstm/vldm register list
+ %C print vscclrm register list
%I print cirrus signed shift immediate: bits 0..3|4..6
%F print the COUNT field of a LFM/SFM instruction.
%P print floating point precision in arithmetic insn
@@ -425,6 +426,12 @@ static const struct sopcode32 coprocessor_opcodes[] =
{ANY, ARM_FEATURE_COPROC (FPU_FPA_EXT_V2),
0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
+ /* Armv8.1-M Mainline instructions. */
+ {T32, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+ 0xec9f0b00, 0xffbf0f01, "vscclrm%c\t%C"},
+ {T32, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN),
+ 0xec9f0a00, 0xffbf0f00, "vscclrm%c\t%C"},
+
/* ARMv8-M Mainline Security Extensions instructions. */
{ANY, ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN),
0xec300a00, 0xfff0ffff, "vlldm\t%16-19r"},
@@ -3642,6 +3649,31 @@ print_insn_coprocessor (bfd_vma pc,
}
break;
+ case 'C':
+ {
+ bfd_boolean single = ((given >> 8) & 1) == 0;
+ char reg_prefix = single ? 's' : 'd';
+ int Dreg = (given >> 22) & 0x1;
+ int Vdreg = (given >> 12) & 0xf;
+ int reg = single ? ((Vdreg << 1) | Dreg)
+ : ((Dreg << 4) | Vdreg);
+ int num = (given >> (single ? 0 : 1)) & 0x7f;
+ int maxreg = single ? 31 : 15;
+ int topreg = reg + num - 1;
+
+ if (!num)
+ func (stream, "{VPR}");
+ else if (num == 1)
+ func (stream, "{%c%d, VPR}", reg_prefix, reg);
+ else if (topreg > maxreg)
+ func (stream, "{%c%d-<overflow reg d%d, VPR}",
+ reg_prefix, reg, single ? topreg >> 1 : topreg);
+ else
+ func (stream, "{%c%d-%c%d, VPR}", reg_prefix, reg,
+ reg_prefix, topreg);
+ }
+ break;
+
case 'u':
if (cond != COND_UNCOND)
is_unpredictable = TRUE;